55f50c7093e056b3e01887785c1606edf01f83ff
[safe/jmp/linux-2.6] / drivers / net / 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 #include <linux/kernel.h>
18 #include <linux/errno.h>
19 #include <linux/pci.h>
20 #include <linux/netdevice.h>
21 #include <linux/delay.h>
22 #include <linux/ethtool.h>
23 #include <linux/mutex.h>
24
25 #include "bnx2x_reg.h"
26 #include "bnx2x_fw_defs.h"
27 #include "bnx2x_hsi.h"
28 #include "bnx2x_link.h"
29 #include "bnx2x.h"
30
31 /********************************************************/
32 #define SUPPORT_CL73 0 /* Currently no */
33 #define ETH_HLEN                        14
34 #define ETH_OVREHEAD            (ETH_HLEN + 8)/* 8 for CRC + VLAN*/
35 #define ETH_MIN_PACKET_SIZE             60
36 #define ETH_MAX_PACKET_SIZE             1500
37 #define ETH_MAX_JUMBO_PACKET_SIZE       9600
38 #define MDIO_ACCESS_TIMEOUT             1000
39 #define BMAC_CONTROL_RX_ENABLE  2
40
41 /***********************************************************/
42 /*                      Shortcut definitions               */
43 /***********************************************************/
44
45 #define NIG_STATUS_XGXS0_LINK10G \
46                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
47 #define NIG_STATUS_XGXS0_LINK_STATUS \
48                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
49 #define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
50                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
51 #define NIG_STATUS_SERDES0_LINK_STATUS \
52                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
53 #define NIG_MASK_MI_INT \
54                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
55 #define NIG_MASK_XGXS0_LINK10G \
56                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
57 #define NIG_MASK_XGXS0_LINK_STATUS \
58                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
59 #define NIG_MASK_SERDES0_LINK_STATUS \
60                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
61
62 #define MDIO_AN_CL73_OR_37_COMPLETE \
63                 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
64                  MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
65
66 #define XGXS_RESET_BITS \
67         (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW |   \
68          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ |      \
69          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN |    \
70          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
71          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
72
73 #define SERDES_RESET_BITS \
74         (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
75          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ |    \
76          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN |  \
77          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
78
79 #define AUTONEG_CL37            SHARED_HW_CFG_AN_ENABLE_CL37
80 #define AUTONEG_CL73            SHARED_HW_CFG_AN_ENABLE_CL73
81 #define AUTONEG_BAM             SHARED_HW_CFG_AN_ENABLE_BAM
82 #define AUTONEG_PARALLEL \
83                                 SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
84 #define AUTONEG_SGMII_FIBER_AUTODET \
85                                 SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
86 #define AUTONEG_REMOTE_PHY      SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
87
88 #define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
89                         MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
90 #define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
91                         MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
92 #define GP_STATUS_SPEED_MASK \
93                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
94 #define GP_STATUS_10M   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
95 #define GP_STATUS_100M  MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
96 #define GP_STATUS_1G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
97 #define GP_STATUS_2_5G  MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
98 #define GP_STATUS_5G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
99 #define GP_STATUS_6G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
100 #define GP_STATUS_10G_HIG \
101                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
102 #define GP_STATUS_10G_CX4 \
103                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
104 #define GP_STATUS_12G_HIG \
105                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG
106 #define GP_STATUS_12_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G
107 #define GP_STATUS_13G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G
108 #define GP_STATUS_15G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G
109 #define GP_STATUS_16G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G
110 #define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
111 #define GP_STATUS_10G_KX4 \
112                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
113
114 #define LINK_10THD                      LINK_STATUS_SPEED_AND_DUPLEX_10THD
115 #define LINK_10TFD                      LINK_STATUS_SPEED_AND_DUPLEX_10TFD
116 #define LINK_100TXHD            LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
117 #define LINK_100T4                      LINK_STATUS_SPEED_AND_DUPLEX_100T4
118 #define LINK_100TXFD            LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
119 #define LINK_1000THD            LINK_STATUS_SPEED_AND_DUPLEX_1000THD
120 #define LINK_1000TFD            LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
121 #define LINK_1000XFD            LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
122 #define LINK_2500THD            LINK_STATUS_SPEED_AND_DUPLEX_2500THD
123 #define LINK_2500TFD            LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
124 #define LINK_2500XFD            LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
125 #define LINK_10GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
126 #define LINK_10GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
127 #define LINK_12GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_12GTFD
128 #define LINK_12GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_12GXFD
129 #define LINK_12_5GTFD           LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD
130 #define LINK_12_5GXFD           LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD
131 #define LINK_13GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_13GTFD
132 #define LINK_13GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_13GXFD
133 #define LINK_15GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_15GTFD
134 #define LINK_15GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_15GXFD
135 #define LINK_16GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_16GTFD
136 #define LINK_16GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_16GXFD
137
138 #define PHY_XGXS_FLAG                   0x1
139 #define PHY_SGMII_FLAG                  0x2
140 #define PHY_SERDES_FLAG                 0x4
141
142 /* */
143 #define SFP_EEPROM_CON_TYPE_ADDR                0x2
144         #define SFP_EEPROM_CON_TYPE_VAL_LC              0x7
145         #define SFP_EEPROM_CON_TYPE_VAL_COPPER  0x21
146
147 #define SFP_EEPROM_FC_TX_TECH_ADDR              0x8
148         #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
149         #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE      0x8
150 #define SFP_EEPROM_VENDOR_NAME_ADDR             0x14
151 #define SFP_EEPROM_VENDOR_NAME_SIZE     16
152 #define SFP_EEPROM_OPTIONS_ADDR                 0x40
153         #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
154 #define SFP_EEPROM_OPTIONS_SIZE                 2
155
156 #define SFP_MODULE_TYPE_UNKNOWN                         0x0
157 #define SFP_MODULE_TYPE_LC                      0x1
158 #define SFP_MODULE_TYPE_ACTIVE_COPPER_CABLE             0x2
159 #define SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE    0x3
160
161 #define SFP_LIMITING_MODE_VALUE                         0x0044
162 /**********************************************************/
163 /*                     INTERFACE                          */
164 /**********************************************************/
165 #define CL45_WR_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
166         bnx2x_cl45_write(_bp, _port, 0, _phy_addr, \
167                 DEFAULT_PHY_DEV_ADDR, \
168                 (_bank + (_addr & 0xf)), \
169                 _val)
170
171 #define CL45_RD_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
172         bnx2x_cl45_read(_bp, _port, 0, _phy_addr, \
173                 DEFAULT_PHY_DEV_ADDR, \
174                 (_bank + (_addr & 0xf)), \
175                 _val)
176
177 static void bnx2x_set_phy_mdio(struct link_params *params)
178 {
179         struct bnx2x *bp = params->bp;
180         REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
181                    params->port*0x18, 0);
182         REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
183                    DEFAULT_PHY_DEV_ADDR);
184 }
185
186 static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
187 {
188         u32 val = REG_RD(bp, reg);
189
190         val |= bits;
191         REG_WR(bp, reg, val);
192         return val;
193 }
194
195 static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
196 {
197         u32 val = REG_RD(bp, reg);
198
199         val &= ~bits;
200         REG_WR(bp, reg, val);
201         return val;
202 }
203
204 static void bnx2x_emac_init(struct link_params *params,
205                            struct link_vars *vars)
206 {
207         /* reset and unreset the emac core */
208         struct bnx2x *bp = params->bp;
209         u8 port = params->port;
210         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
211         u32 val;
212         u16 timeout;
213
214         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
215                    (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
216         udelay(5);
217         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
218                    (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
219
220         /* init emac - use read-modify-write */
221         /* self clear reset */
222         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
223         EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
224
225         timeout = 200;
226         do {
227                 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
228                 DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
229                 if (!timeout) {
230                         DP(NETIF_MSG_LINK, "EMAC timeout!\n");
231                         return;
232                 }
233                 timeout--;
234         } while (val & EMAC_MODE_RESET);
235
236         /* Set mac address */
237         val = ((params->mac_addr[0] << 8) |
238                 params->mac_addr[1]);
239         EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH, val);
240
241         val = ((params->mac_addr[2] << 24) |
242                (params->mac_addr[3] << 16) |
243                (params->mac_addr[4] << 8) |
244                 params->mac_addr[5]);
245         EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val);
246 }
247
248 static u8 bnx2x_emac_enable(struct link_params *params,
249                           struct link_vars *vars, u8 lb)
250 {
251         struct bnx2x *bp = params->bp;
252         u8 port = params->port;
253         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
254         u32 val;
255
256         DP(NETIF_MSG_LINK, "enabling EMAC\n");
257
258         /* enable emac and not bmac */
259         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
260
261         /* for paladium */
262         if (CHIP_REV_IS_EMUL(bp)) {
263                 /* Use lane 1 (of lanes 0-3) */
264                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
265                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
266                             port*4, 1);
267         }
268         /* for fpga */
269         else
270
271         if (CHIP_REV_IS_FPGA(bp)) {
272                 /* Use lane 1 (of lanes 0-3) */
273                 DP(NETIF_MSG_LINK, "bnx2x_emac_enable: Setting FPGA\n");
274
275                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
276                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4,
277                             0);
278         } else
279         /* ASIC */
280         if (vars->phy_flags & PHY_XGXS_FLAG) {
281                 u32 ser_lane = ((params->lane_config &
282                             PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
283                             PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
284
285                 DP(NETIF_MSG_LINK, "XGXS\n");
286                 /* select the master lanes (out of 0-3) */
287                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 +
288                            port*4, ser_lane);
289                 /* select XGXS */
290                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
291                            port*4, 1);
292
293         } else { /* SerDes */
294                 DP(NETIF_MSG_LINK, "SerDes\n");
295                 /* select SerDes */
296                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
297                            port*4, 0);
298         }
299
300         /* enable emac */
301         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
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         }
374
375         vars->mac_type = MAC_TYPE_EMAC;
376         return 0;
377 }
378
379
380
381 static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
382                           u8 is_lb)
383 {
384         struct bnx2x *bp = params->bp;
385         u8 port = params->port;
386         u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
387                                NIG_REG_INGRESS_BMAC0_MEM;
388         u32 wb_data[2];
389         u32 val;
390
391         DP(NETIF_MSG_LINK, "Enabling BigMAC\n");
392         /* reset and unreset the BigMac */
393         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
394                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
395         msleep(1);
396
397         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
398                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
399
400         /* enable access for bmac registers */
401         REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
402
403         /* XGXS control */
404         wb_data[0] = 0x3c;
405         wb_data[1] = 0;
406         REG_WR_DMAE(bp, bmac_addr +
407                       BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
408                       wb_data, 2);
409
410         /* tx MAC SA */
411         wb_data[0] = ((params->mac_addr[2] << 24) |
412                        (params->mac_addr[3] << 16) |
413                        (params->mac_addr[4] << 8) |
414                         params->mac_addr[5]);
415         wb_data[1] = ((params->mac_addr[0] << 8) |
416                         params->mac_addr[1]);
417         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR,
418                     wb_data, 2);
419
420         /* tx control */
421         val = 0xc0;
422         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
423                 val |= 0x800000;
424         wb_data[0] = val;
425         wb_data[1] = 0;
426         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL,
427                         wb_data, 2);
428
429         /* mac control */
430         val = 0x3;
431         if (is_lb) {
432                 val |= 0x4;
433                 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
434         }
435         wb_data[0] = val;
436         wb_data[1] = 0;
437         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
438                     wb_data, 2);
439
440
441         /* set rx mtu */
442         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
443         wb_data[1] = 0;
444         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE,
445                         wb_data, 2);
446
447         /* rx control set to don't strip crc */
448         val = 0x14;
449         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
450                 val |= 0x20;
451         wb_data[0] = val;
452         wb_data[1] = 0;
453         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL,
454                         wb_data, 2);
455
456         /* set tx mtu */
457         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
458         wb_data[1] = 0;
459         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE,
460                         wb_data, 2);
461
462         /* set cnt max size */
463         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
464         wb_data[1] = 0;
465         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE,
466                     wb_data, 2);
467
468         /* configure safc */
469         wb_data[0] = 0x1000200;
470         wb_data[1] = 0;
471         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
472                     wb_data, 2);
473         /* fix for emulation */
474         if (CHIP_REV_IS_EMUL(bp)) {
475                 wb_data[0] = 0xf000;
476                 wb_data[1] = 0;
477                 REG_WR_DMAE(bp,
478                             bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
479                             wb_data, 2);
480         }
481
482         REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
483         REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
484         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
485         val = 0;
486         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
487                 val = 1;
488         REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
489         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
490         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
491         REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
492         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
493         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
494
495         vars->mac_type = MAC_TYPE_BMAC;
496         return 0;
497 }
498
499 static void bnx2x_phy_deassert(struct link_params *params, u8 phy_flags)
500 {
501         struct bnx2x *bp = params->bp;
502         u32 val;
503
504         if (phy_flags & PHY_XGXS_FLAG) {
505                 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:XGXS\n");
506                 val = XGXS_RESET_BITS;
507
508         } else { /* SerDes */
509                 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:SerDes\n");
510                 val = SERDES_RESET_BITS;
511         }
512
513         val = val << (params->port*16);
514
515         /* reset and unreset the SerDes/XGXS */
516         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
517                     val);
518         udelay(500);
519         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET,
520                     val);
521         bnx2x_set_phy_mdio(params);
522 }
523
524 void bnx2x_link_status_update(struct link_params *params,
525                             struct link_vars   *vars)
526 {
527         struct bnx2x *bp = params->bp;
528         u8 link_10g;
529         u8 port = params->port;
530
531         if (params->switch_cfg ==  SWITCH_CFG_1G)
532                 vars->phy_flags = PHY_SERDES_FLAG;
533         else
534                 vars->phy_flags = PHY_XGXS_FLAG;
535         vars->link_status = REG_RD(bp, params->shmem_base +
536                                           offsetof(struct shmem_region,
537                                            port_mb[port].link_status));
538
539         vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
540
541         if (vars->link_up) {
542                 DP(NETIF_MSG_LINK, "phy link up\n");
543
544                 vars->phy_link_up = 1;
545                 vars->duplex = DUPLEX_FULL;
546                 switch (vars->link_status &
547                                         LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
548                         case LINK_10THD:
549                                 vars->duplex = DUPLEX_HALF;
550                                 /* fall thru */
551                         case LINK_10TFD:
552                                 vars->line_speed = SPEED_10;
553                                 break;
554
555                         case LINK_100TXHD:
556                                 vars->duplex = DUPLEX_HALF;
557                                 /* fall thru */
558                         case LINK_100T4:
559                         case LINK_100TXFD:
560                                 vars->line_speed = SPEED_100;
561                                 break;
562
563                         case LINK_1000THD:
564                                 vars->duplex = DUPLEX_HALF;
565                                 /* fall thru */
566                         case LINK_1000TFD:
567                                 vars->line_speed = SPEED_1000;
568                                 break;
569
570                         case LINK_2500THD:
571                                 vars->duplex = DUPLEX_HALF;
572                                 /* fall thru */
573                         case LINK_2500TFD:
574                                 vars->line_speed = SPEED_2500;
575                                 break;
576
577                         case LINK_10GTFD:
578                                 vars->line_speed = SPEED_10000;
579                                 break;
580
581                         case LINK_12GTFD:
582                                 vars->line_speed = SPEED_12000;
583                                 break;
584
585                         case LINK_12_5GTFD:
586                                 vars->line_speed = SPEED_12500;
587                                 break;
588
589                         case LINK_13GTFD:
590                                 vars->line_speed = SPEED_13000;
591                                 break;
592
593                         case LINK_15GTFD:
594                                 vars->line_speed = SPEED_15000;
595                                 break;
596
597                         case LINK_16GTFD:
598                                 vars->line_speed = SPEED_16000;
599                                 break;
600
601                         default:
602                                 break;
603                 }
604
605                 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
606                         vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
607                 else
608                         vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_TX;
609
610                 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
611                         vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
612                 else
613                         vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_RX;
614
615                 if (vars->phy_flags & PHY_XGXS_FLAG) {
616                         if (vars->line_speed &&
617                             ((vars->line_speed == SPEED_10) ||
618                              (vars->line_speed == SPEED_100))) {
619                                 vars->phy_flags |= PHY_SGMII_FLAG;
620                         } else {
621                                 vars->phy_flags &= ~PHY_SGMII_FLAG;
622                         }
623                 }
624
625                 /* anything 10 and over uses the bmac */
626                 link_10g = ((vars->line_speed == SPEED_10000) ||
627                             (vars->line_speed == SPEED_12000) ||
628                             (vars->line_speed == SPEED_12500) ||
629                             (vars->line_speed == SPEED_13000) ||
630                             (vars->line_speed == SPEED_15000) ||
631                             (vars->line_speed == SPEED_16000));
632                 if (link_10g)
633                         vars->mac_type = MAC_TYPE_BMAC;
634                 else
635                         vars->mac_type = MAC_TYPE_EMAC;
636
637         } else { /* link down */
638                 DP(NETIF_MSG_LINK, "phy link down\n");
639
640                 vars->phy_link_up = 0;
641
642                 vars->line_speed = 0;
643                 vars->duplex = DUPLEX_FULL;
644                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
645
646                 /* indicate no mac active */
647                 vars->mac_type = MAC_TYPE_NONE;
648         }
649
650         DP(NETIF_MSG_LINK, "link_status 0x%x  phy_link_up %x\n",
651                  vars->link_status, vars->phy_link_up);
652         DP(NETIF_MSG_LINK, "line_speed %x  duplex %x  flow_ctrl 0x%x\n",
653                  vars->line_speed, vars->duplex, vars->flow_ctrl);
654 }
655
656 static void bnx2x_update_mng(struct link_params *params, u32 link_status)
657 {
658         struct bnx2x *bp = params->bp;
659         REG_WR(bp, params->shmem_base +
660                    offsetof(struct shmem_region,
661                             port_mb[params->port].link_status),
662                         link_status);
663 }
664
665 static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
666 {
667         u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
668                 NIG_REG_INGRESS_BMAC0_MEM;
669         u32 wb_data[2];
670         u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
671
672         /* Only if the bmac is out of reset */
673         if (REG_RD(bp, MISC_REG_RESET_REG_2) &
674                         (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
675             nig_bmac_enable) {
676
677                 /* Clear Rx Enable bit in BMAC_CONTROL register */
678                 REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
679                             wb_data, 2);
680                 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
681                 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
682                             wb_data, 2);
683
684                 msleep(1);
685         }
686 }
687
688 static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
689                          u32 line_speed)
690 {
691         struct bnx2x *bp = params->bp;
692         u8 port = params->port;
693         u32 init_crd, crd;
694         u32 count = 1000;
695
696         /* disable port */
697         REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
698
699         /* wait for init credit */
700         init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
701         crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
702         DP(NETIF_MSG_LINK, "init_crd 0x%x  crd 0x%x\n", init_crd, crd);
703
704         while ((init_crd != crd) && count) {
705                 msleep(5);
706
707                 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
708                 count--;
709         }
710         crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
711         if (init_crd != crd) {
712                 DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
713                           init_crd, crd);
714                 return -EINVAL;
715         }
716
717         if (flow_ctrl & BNX2X_FLOW_CTRL_RX ||
718             line_speed == SPEED_10 ||
719             line_speed == SPEED_100 ||
720             line_speed == SPEED_1000 ||
721             line_speed == SPEED_2500) {
722                 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
723                 /* update threshold */
724                 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
725                 /* update init credit */
726                 init_crd = 778;         /* (800-18-4) */
727
728         } else {
729                 u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
730                               ETH_OVREHEAD)/16;
731                 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
732                 /* update threshold */
733                 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
734                 /* update init credit */
735                 switch (line_speed) {
736                 case SPEED_10000:
737                         init_crd = thresh + 553 - 22;
738                         break;
739
740                 case SPEED_12000:
741                         init_crd = thresh + 664 - 22;
742                         break;
743
744                 case SPEED_13000:
745                         init_crd = thresh + 742 - 22;
746                         break;
747
748                 case SPEED_16000:
749                         init_crd = thresh + 778 - 22;
750                         break;
751                 default:
752                         DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
753                                   line_speed);
754                         return -EINVAL;
755                         break;
756                 }
757         }
758         REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
759         DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
760                  line_speed, init_crd);
761
762         /* probe the credit changes */
763         REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
764         msleep(5);
765         REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
766
767         /* enable port */
768         REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
769         return 0;
770 }
771
772 static u32 bnx2x_get_emac_base(struct bnx2x *bp, u32 ext_phy_type, u8 port)
773 {
774         u32 emac_base;
775         switch (ext_phy_type) {
776         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
777         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
778                 /* All MDC/MDIO is directed through single EMAC */
779                 if (REG_RD(bp, NIG_REG_PORT_SWAP))
780                         emac_base = GRCBASE_EMAC0;
781                 else
782                         emac_base = GRCBASE_EMAC1;
783                 break;
784         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
785                 emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
786                 break;
787         default:
788                 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
789                 break;
790         }
791         return emac_base;
792
793 }
794
795 u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
796                   u8 phy_addr, u8 devad, u16 reg, u16 val)
797 {
798         u32 tmp, saved_mode;
799         u8 i, rc = 0;
800         u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
801
802         /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
803          * (a value of 49==0x31) and make sure that the AUTO poll is off
804          */
805
806         saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
807         tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
808                              EMAC_MDIO_MODE_CLOCK_CNT);
809         tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
810                 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
811         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
812         REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
813         udelay(40);
814
815         /* address */
816
817         tmp = ((phy_addr << 21) | (devad << 16) | reg |
818                EMAC_MDIO_COMM_COMMAND_ADDRESS |
819                EMAC_MDIO_COMM_START_BUSY);
820         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
821
822         for (i = 0; i < 50; i++) {
823                 udelay(10);
824
825                 tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
826                 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
827                         udelay(5);
828                         break;
829                 }
830         }
831         if (tmp & EMAC_MDIO_COMM_START_BUSY) {
832                 DP(NETIF_MSG_LINK, "write phy register failed\n");
833                 rc = -EFAULT;
834         } else {
835                 /* data */
836                 tmp = ((phy_addr << 21) | (devad << 16) | val |
837                        EMAC_MDIO_COMM_COMMAND_WRITE_45 |
838                        EMAC_MDIO_COMM_START_BUSY);
839                 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
840
841                 for (i = 0; i < 50; i++) {
842                         udelay(10);
843
844                         tmp = REG_RD(bp, mdio_ctrl +
845                                          EMAC_REG_EMAC_MDIO_COMM);
846                         if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
847                                 udelay(5);
848                                 break;
849                         }
850                 }
851                 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
852                         DP(NETIF_MSG_LINK, "write phy register failed\n");
853                         rc = -EFAULT;
854                 }
855         }
856
857         /* Restore the saved mode */
858         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
859
860         return rc;
861 }
862
863 u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
864                  u8 phy_addr, u8 devad, u16 reg, u16 *ret_val)
865 {
866         u32 val, saved_mode;
867         u16 i;
868         u8 rc = 0;
869
870         u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
871         /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
872          * (a value of 49==0x31) and make sure that the AUTO poll is off
873          */
874
875         saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
876         val = saved_mode & ((EMAC_MDIO_MODE_AUTO_POLL |
877                              EMAC_MDIO_MODE_CLOCK_CNT));
878         val |= (EMAC_MDIO_MODE_CLAUSE_45 |
879                 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
880         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
881         REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
882         udelay(40);
883
884         /* address */
885         val = ((phy_addr << 21) | (devad << 16) | reg |
886                EMAC_MDIO_COMM_COMMAND_ADDRESS |
887                EMAC_MDIO_COMM_START_BUSY);
888         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
889
890         for (i = 0; i < 50; i++) {
891                 udelay(10);
892
893                 val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
894                 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
895                         udelay(5);
896                         break;
897                 }
898         }
899         if (val & EMAC_MDIO_COMM_START_BUSY) {
900                 DP(NETIF_MSG_LINK, "read phy register failed\n");
901
902                 *ret_val = 0;
903                 rc = -EFAULT;
904
905         } else {
906                 /* data */
907                 val = ((phy_addr << 21) | (devad << 16) |
908                        EMAC_MDIO_COMM_COMMAND_READ_45 |
909                        EMAC_MDIO_COMM_START_BUSY);
910                 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
911
912                 for (i = 0; i < 50; i++) {
913                         udelay(10);
914
915                         val = REG_RD(bp, mdio_ctrl +
916                                           EMAC_REG_EMAC_MDIO_COMM);
917                         if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
918                                 *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
919                                 break;
920                         }
921                 }
922                 if (val & EMAC_MDIO_COMM_START_BUSY) {
923                         DP(NETIF_MSG_LINK, "read phy register failed\n");
924
925                         *ret_val = 0;
926                         rc = -EFAULT;
927                 }
928         }
929
930         /* Restore the saved mode */
931         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
932
933         return rc;
934 }
935
936 static void bnx2x_set_aer_mmd(struct link_params *params,
937                             struct link_vars   *vars)
938 {
939         struct bnx2x *bp = params->bp;
940         u32 ser_lane;
941         u16 offset;
942
943         ser_lane = ((params->lane_config &
944                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
945                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
946
947         offset = (vars->phy_flags & PHY_XGXS_FLAG) ?
948                 (params->phy_addr + ser_lane) : 0;
949
950         CL45_WR_OVER_CL22(bp, params->port,
951                               params->phy_addr,
952                               MDIO_REG_BANK_AER_BLOCK,
953                               MDIO_AER_BLOCK_AER_REG, 0x3800 + offset);
954 }
955
956 static void bnx2x_set_master_ln(struct link_params *params)
957 {
958         struct bnx2x *bp = params->bp;
959         u16 new_master_ln, ser_lane;
960         ser_lane =  ((params->lane_config &
961                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
962                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
963
964         /* set the master_ln for AN */
965         CL45_RD_OVER_CL22(bp, params->port,
966                               params->phy_addr,
967                               MDIO_REG_BANK_XGXS_BLOCK2,
968                               MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
969                               &new_master_ln);
970
971         CL45_WR_OVER_CL22(bp, params->port,
972                               params->phy_addr,
973                               MDIO_REG_BANK_XGXS_BLOCK2 ,
974                               MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
975                               (new_master_ln | ser_lane));
976 }
977
978 static u8 bnx2x_reset_unicore(struct link_params *params)
979 {
980         struct bnx2x *bp = params->bp;
981         u16 mii_control;
982         u16 i;
983
984         CL45_RD_OVER_CL22(bp, params->port,
985                               params->phy_addr,
986                               MDIO_REG_BANK_COMBO_IEEE0,
987                               MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
988
989         /* reset the unicore */
990         CL45_WR_OVER_CL22(bp, params->port,
991                               params->phy_addr,
992                               MDIO_REG_BANK_COMBO_IEEE0,
993                               MDIO_COMBO_IEEE0_MII_CONTROL,
994                               (mii_control |
995                                MDIO_COMBO_IEEO_MII_CONTROL_RESET));
996
997         /* wait for the reset to self clear */
998         for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
999                 udelay(5);
1000
1001                 /* the reset erased the previous bank value */
1002                 CL45_RD_OVER_CL22(bp, params->port,
1003                                       params->phy_addr,
1004                               MDIO_REG_BANK_COMBO_IEEE0,
1005                               MDIO_COMBO_IEEE0_MII_CONTROL,
1006                               &mii_control);
1007
1008                 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
1009                         udelay(5);
1010                         return 0;
1011                 }
1012         }
1013
1014         DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
1015         return -EINVAL;
1016
1017 }
1018
1019 static void bnx2x_set_swap_lanes(struct link_params *params)
1020 {
1021         struct bnx2x *bp = params->bp;
1022         /* Each two bits represents a lane number:
1023            No swap is 0123 => 0x1b no need to enable the swap */
1024         u16 ser_lane, rx_lane_swap, tx_lane_swap;
1025
1026         ser_lane = ((params->lane_config &
1027                          PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1028                         PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1029         rx_lane_swap = ((params->lane_config &
1030                              PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
1031                             PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
1032         tx_lane_swap = ((params->lane_config &
1033                              PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
1034                             PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
1035
1036         if (rx_lane_swap != 0x1b) {
1037                 CL45_WR_OVER_CL22(bp, params->port,
1038                                       params->phy_addr,
1039                                     MDIO_REG_BANK_XGXS_BLOCK2,
1040                                     MDIO_XGXS_BLOCK2_RX_LN_SWAP,
1041                                     (rx_lane_swap |
1042                                     MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
1043                                     MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
1044         } else {
1045                 CL45_WR_OVER_CL22(bp, params->port,
1046                                       params->phy_addr,
1047                                       MDIO_REG_BANK_XGXS_BLOCK2,
1048                                       MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
1049         }
1050
1051         if (tx_lane_swap != 0x1b) {
1052                 CL45_WR_OVER_CL22(bp, params->port,
1053                                       params->phy_addr,
1054                                       MDIO_REG_BANK_XGXS_BLOCK2,
1055                                       MDIO_XGXS_BLOCK2_TX_LN_SWAP,
1056                                       (tx_lane_swap |
1057                                        MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
1058         } else {
1059                 CL45_WR_OVER_CL22(bp, params->port,
1060                                       params->phy_addr,
1061                                       MDIO_REG_BANK_XGXS_BLOCK2,
1062                                       MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
1063         }
1064 }
1065
1066 static void bnx2x_set_parallel_detection(struct link_params *params,
1067                                        u8                phy_flags)
1068 {
1069         struct bnx2x *bp = params->bp;
1070         u16 control2;
1071
1072         CL45_RD_OVER_CL22(bp, params->port,
1073                               params->phy_addr,
1074                               MDIO_REG_BANK_SERDES_DIGITAL,
1075                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1076                               &control2);
1077
1078
1079         control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
1080
1081
1082         CL45_WR_OVER_CL22(bp, params->port,
1083                               params->phy_addr,
1084                               MDIO_REG_BANK_SERDES_DIGITAL,
1085                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1086                               control2);
1087
1088         if (phy_flags & PHY_XGXS_FLAG) {
1089                 DP(NETIF_MSG_LINK, "XGXS\n");
1090
1091                 CL45_WR_OVER_CL22(bp, params->port,
1092                                       params->phy_addr,
1093                                 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1094                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
1095                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
1096
1097                 CL45_RD_OVER_CL22(bp, params->port,
1098                                       params->phy_addr,
1099                                 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1100                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1101                                 &control2);
1102
1103
1104                 control2 |=
1105                     MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
1106
1107                 CL45_WR_OVER_CL22(bp, params->port,
1108                                       params->phy_addr,
1109                                 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1110                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1111                                 control2);
1112
1113                 /* Disable parallel detection of HiG */
1114                 CL45_WR_OVER_CL22(bp, params->port,
1115                                       params->phy_addr,
1116                                 MDIO_REG_BANK_XGXS_BLOCK2,
1117                                 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
1118                                 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
1119                                 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
1120         }
1121 }
1122
1123 static void bnx2x_set_autoneg(struct link_params *params,
1124                             struct link_vars   *vars)
1125 {
1126         struct bnx2x *bp = params->bp;
1127         u16 reg_val;
1128
1129         /* CL37 Autoneg */
1130
1131         CL45_RD_OVER_CL22(bp, params->port,
1132                               params->phy_addr,
1133                               MDIO_REG_BANK_COMBO_IEEE0,
1134                               MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
1135
1136         /* CL37 Autoneg Enabled */
1137         if (vars->line_speed == SPEED_AUTO_NEG)
1138                 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
1139         else /* CL37 Autoneg Disabled */
1140                 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1141                              MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
1142
1143         CL45_WR_OVER_CL22(bp, params->port,
1144                               params->phy_addr,
1145                               MDIO_REG_BANK_COMBO_IEEE0,
1146                               MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1147
1148         /* Enable/Disable Autodetection */
1149
1150         CL45_RD_OVER_CL22(bp, params->port,
1151                               params->phy_addr,
1152                               MDIO_REG_BANK_SERDES_DIGITAL,
1153                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
1154         reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN;
1155         if (vars->line_speed == SPEED_AUTO_NEG)
1156                 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1157         else
1158                 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1159
1160         CL45_WR_OVER_CL22(bp, params->port,
1161                               params->phy_addr,
1162                               MDIO_REG_BANK_SERDES_DIGITAL,
1163                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
1164
1165         /* Enable TetonII and BAM autoneg */
1166         CL45_RD_OVER_CL22(bp, params->port,
1167                               params->phy_addr,
1168                               MDIO_REG_BANK_BAM_NEXT_PAGE,
1169                               MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1170                           &reg_val);
1171         if (vars->line_speed == SPEED_AUTO_NEG) {
1172                 /* Enable BAM aneg Mode and TetonII aneg Mode */
1173                 reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1174                             MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1175         } else {
1176                 /* TetonII and BAM Autoneg Disabled */
1177                 reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1178                              MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1179         }
1180         CL45_WR_OVER_CL22(bp, params->port,
1181                               params->phy_addr,
1182                               MDIO_REG_BANK_BAM_NEXT_PAGE,
1183                               MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1184                               reg_val);
1185
1186         /* Enable Clause 73 Aneg */
1187         if ((vars->line_speed == SPEED_AUTO_NEG) &&
1188             (SUPPORT_CL73)) {
1189                 /* Enable BAM Station Manager */
1190
1191                 CL45_WR_OVER_CL22(bp, params->port,
1192                                       params->phy_addr,
1193                                       MDIO_REG_BANK_CL73_USERB0,
1194                                       MDIO_CL73_USERB0_CL73_BAM_CTRL1,
1195                                    (MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
1196                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
1197                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN));
1198
1199                 /* Merge CL73 and CL37 aneg resolution */
1200                 CL45_RD_OVER_CL22(bp, params->port,
1201                                       params->phy_addr,
1202                                       MDIO_REG_BANK_CL73_USERB0,
1203                                       MDIO_CL73_USERB0_CL73_BAM_CTRL3,
1204                                       &reg_val);
1205
1206                 CL45_WR_OVER_CL22(bp, params->port,
1207                                       params->phy_addr,
1208                         MDIO_REG_BANK_CL73_USERB0,
1209                         MDIO_CL73_USERB0_CL73_BAM_CTRL3,
1210                         (reg_val |
1211                         MDIO_CL73_USERB0_CL73_BAM_CTRL3_USE_CL73_HCD_MR));
1212
1213                 /* Set the CL73 AN speed */
1214
1215                 CL45_RD_OVER_CL22(bp, params->port,
1216                                       params->phy_addr,
1217                                       MDIO_REG_BANK_CL73_IEEEB1,
1218                                       MDIO_CL73_IEEEB1_AN_ADV2, &reg_val);
1219                 /* In the SerDes we support only the 1G.
1220                    In the XGXS we support the 10G KX4
1221                    but we currently do not support the KR */
1222                 if (vars->phy_flags & PHY_XGXS_FLAG) {
1223                         DP(NETIF_MSG_LINK, "XGXS\n");
1224                         /* 10G KX4 */
1225                         reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
1226                 } else {
1227                         DP(NETIF_MSG_LINK, "SerDes\n");
1228                         /* 1000M KX */
1229                         reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
1230                 }
1231                 CL45_WR_OVER_CL22(bp, params->port,
1232                                       params->phy_addr,
1233                                       MDIO_REG_BANK_CL73_IEEEB1,
1234                                       MDIO_CL73_IEEEB1_AN_ADV2, reg_val);
1235
1236                 /* CL73 Autoneg Enabled */
1237                 reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
1238         } else {
1239                 /* CL73 Autoneg Disabled */
1240                 reg_val = 0;
1241         }
1242         CL45_WR_OVER_CL22(bp, params->port,
1243                               params->phy_addr,
1244                               MDIO_REG_BANK_CL73_IEEEB0,
1245                               MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
1246 }
1247
1248 /* program SerDes, forced speed */
1249 static void bnx2x_program_serdes(struct link_params *params,
1250                                struct link_vars *vars)
1251 {
1252         struct bnx2x *bp = params->bp;
1253         u16 reg_val;
1254
1255         /* program duplex, disable autoneg */
1256
1257         CL45_RD_OVER_CL22(bp, params->port,
1258                               params->phy_addr,
1259                               MDIO_REG_BANK_COMBO_IEEE0,
1260                               MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
1261         reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
1262                      MDIO_COMBO_IEEO_MII_CONTROL_AN_EN);
1263         if (params->req_duplex == DUPLEX_FULL)
1264                 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1265         CL45_WR_OVER_CL22(bp, params->port,
1266                               params->phy_addr,
1267                               MDIO_REG_BANK_COMBO_IEEE0,
1268                               MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1269
1270         /* program speed
1271            - needed only if the speed is greater than 1G (2.5G or 10G) */
1272         CL45_RD_OVER_CL22(bp, params->port,
1273                                       params->phy_addr,
1274                                       MDIO_REG_BANK_SERDES_DIGITAL,
1275                                       MDIO_SERDES_DIGITAL_MISC1, &reg_val);
1276         /* clearing the speed value before setting the right speed */
1277         DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
1278
1279         reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
1280                      MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1281
1282         if (!((vars->line_speed == SPEED_1000) ||
1283               (vars->line_speed == SPEED_100) ||
1284               (vars->line_speed == SPEED_10))) {
1285
1286                 reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
1287                             MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1288                 if (vars->line_speed == SPEED_10000)
1289                         reg_val |=
1290                                 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
1291                 if (vars->line_speed == SPEED_13000)
1292                         reg_val |=
1293                                 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G;
1294         }
1295
1296         CL45_WR_OVER_CL22(bp, params->port,
1297                                       params->phy_addr,
1298                                       MDIO_REG_BANK_SERDES_DIGITAL,
1299                                       MDIO_SERDES_DIGITAL_MISC1, reg_val);
1300
1301 }
1302
1303 static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params)
1304 {
1305         struct bnx2x *bp = params->bp;
1306         u16 val = 0;
1307
1308         /* configure the 48 bits for BAM AN */
1309
1310         /* set extended capabilities */
1311         if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
1312                 val |= MDIO_OVER_1G_UP1_2_5G;
1313         if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
1314                 val |= MDIO_OVER_1G_UP1_10G;
1315         CL45_WR_OVER_CL22(bp, params->port,
1316                               params->phy_addr,
1317                               MDIO_REG_BANK_OVER_1G,
1318                               MDIO_OVER_1G_UP1, val);
1319
1320         CL45_WR_OVER_CL22(bp, params->port,
1321                               params->phy_addr,
1322                               MDIO_REG_BANK_OVER_1G,
1323                               MDIO_OVER_1G_UP3, 0);
1324 }
1325
1326 static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u32 *ieee_fc)
1327 {
1328         *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
1329         /* resolve pause mode and advertisement
1330          * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
1331
1332         switch (params->req_flow_ctrl) {
1333         case BNX2X_FLOW_CTRL_AUTO:
1334                 if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH) {
1335                         *ieee_fc |=
1336                              MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1337                 } else {
1338                         *ieee_fc |=
1339                        MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1340                 }
1341                 break;
1342         case BNX2X_FLOW_CTRL_TX:
1343                 *ieee_fc |=
1344                        MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1345                 break;
1346
1347         case BNX2X_FLOW_CTRL_RX:
1348         case BNX2X_FLOW_CTRL_BOTH:
1349                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1350                 break;
1351
1352         case BNX2X_FLOW_CTRL_NONE:
1353         default:
1354                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
1355                 break;
1356         }
1357 }
1358
1359 static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params,
1360                                            u32 ieee_fc)
1361 {
1362         struct bnx2x *bp = params->bp;
1363         /* for AN, we are always publishing full duplex */
1364
1365         CL45_WR_OVER_CL22(bp, params->port,
1366                               params->phy_addr,
1367                               MDIO_REG_BANK_COMBO_IEEE0,
1368                               MDIO_COMBO_IEEE0_AUTO_NEG_ADV, (u16)ieee_fc);
1369 }
1370
1371 static void bnx2x_restart_autoneg(struct link_params *params)
1372 {
1373         struct bnx2x *bp = params->bp;
1374         DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
1375         if (SUPPORT_CL73) {
1376                 /* enable and restart clause 73 aneg */
1377                 u16 an_ctrl;
1378
1379                 CL45_RD_OVER_CL22(bp, params->port,
1380                                       params->phy_addr,
1381                                       MDIO_REG_BANK_CL73_IEEEB0,
1382                                       MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1383                                   &an_ctrl);
1384                 CL45_WR_OVER_CL22(bp, params->port,
1385                                       params->phy_addr,
1386                                 MDIO_REG_BANK_CL73_IEEEB0,
1387                                 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1388                                 (an_ctrl |
1389                                 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
1390                                 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
1391
1392         } else {
1393                 /* Enable and restart BAM/CL37 aneg */
1394                 u16 mii_control;
1395
1396                 CL45_RD_OVER_CL22(bp, params->port,
1397                                       params->phy_addr,
1398                                       MDIO_REG_BANK_COMBO_IEEE0,
1399                                       MDIO_COMBO_IEEE0_MII_CONTROL,
1400                                       &mii_control);
1401                 DP(NETIF_MSG_LINK,
1402                          "bnx2x_restart_autoneg mii_control before = 0x%x\n",
1403                          mii_control);
1404                 CL45_WR_OVER_CL22(bp, params->port,
1405                                       params->phy_addr,
1406                                       MDIO_REG_BANK_COMBO_IEEE0,
1407                                       MDIO_COMBO_IEEE0_MII_CONTROL,
1408                                       (mii_control |
1409                                 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1410                                 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
1411         }
1412 }
1413
1414 static void bnx2x_initialize_sgmii_process(struct link_params *params,
1415                                          struct link_vars *vars)
1416 {
1417         struct bnx2x *bp = params->bp;
1418         u16 control1;
1419
1420         /* in SGMII mode, the unicore is always slave */
1421
1422         CL45_RD_OVER_CL22(bp, params->port,
1423                               params->phy_addr,
1424                               MDIO_REG_BANK_SERDES_DIGITAL,
1425                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1426                       &control1);
1427         control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
1428         /* set sgmii mode (and not fiber) */
1429         control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
1430                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
1431                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
1432         CL45_WR_OVER_CL22(bp, params->port,
1433                               params->phy_addr,
1434                               MDIO_REG_BANK_SERDES_DIGITAL,
1435                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1436                               control1);
1437
1438         /* if forced speed */
1439         if (!(vars->line_speed == SPEED_AUTO_NEG)) {
1440                 /* set speed, disable autoneg */
1441                 u16 mii_control;
1442
1443                 CL45_RD_OVER_CL22(bp, params->port,
1444                                       params->phy_addr,
1445                                       MDIO_REG_BANK_COMBO_IEEE0,
1446                                       MDIO_COMBO_IEEE0_MII_CONTROL,
1447                                       &mii_control);
1448                 mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1449                                  MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
1450                                  MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
1451
1452                 switch (vars->line_speed) {
1453                 case SPEED_100:
1454                         mii_control |=
1455                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
1456                         break;
1457                 case SPEED_1000:
1458                         mii_control |=
1459                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
1460                         break;
1461                 case SPEED_10:
1462                         /* there is nothing to set for 10M */
1463                         break;
1464                 default:
1465                         /* invalid speed for SGMII */
1466                         DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
1467                                   vars->line_speed);
1468                         break;
1469                 }
1470
1471                 /* setting the full duplex */
1472                 if (params->req_duplex == DUPLEX_FULL)
1473                         mii_control |=
1474                                 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1475                 CL45_WR_OVER_CL22(bp, params->port,
1476                                       params->phy_addr,
1477                                       MDIO_REG_BANK_COMBO_IEEE0,
1478                                       MDIO_COMBO_IEEE0_MII_CONTROL,
1479                                       mii_control);
1480
1481         } else { /* AN mode */
1482                 /* enable and restart AN */
1483                 bnx2x_restart_autoneg(params);
1484         }
1485 }
1486
1487
1488 /*
1489  * link management
1490  */
1491
1492 static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
1493 {                                               /*  LD      LP   */
1494         switch (pause_result) {                 /* ASYM P ASYM P */
1495         case 0xb:                               /*   1  0   1  1 */
1496                 vars->flow_ctrl = BNX2X_FLOW_CTRL_TX;
1497                 break;
1498
1499         case 0xe:                               /*   1  1   1  0 */
1500                 vars->flow_ctrl = BNX2X_FLOW_CTRL_RX;
1501                 break;
1502
1503         case 0x5:                               /*   0  1   0  1 */
1504         case 0x7:                               /*   0  1   1  1 */
1505         case 0xd:                               /*   1  1   0  1 */
1506         case 0xf:                               /*   1  1   1  1 */
1507                 vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
1508                 break;
1509
1510         default:
1511                 break;
1512         }
1513 }
1514
1515 static u8 bnx2x_ext_phy_resove_fc(struct link_params *params,
1516                                   struct link_vars *vars)
1517 {
1518         struct bnx2x *bp = params->bp;
1519         u8 ext_phy_addr;
1520         u16 ld_pause;   /* local */
1521         u16 lp_pause;   /* link partner */
1522         u16 an_complete; /* AN complete */
1523         u16 pause_result;
1524         u8 ret = 0;
1525         u32 ext_phy_type;
1526         u8 port = params->port;
1527         ext_phy_addr = ((params->ext_phy_config &
1528                          PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1529                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1530
1531         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1532         /* read twice */
1533
1534         bnx2x_cl45_read(bp, port,
1535                       ext_phy_type,
1536                       ext_phy_addr,
1537                       MDIO_AN_DEVAD,
1538                       MDIO_AN_REG_STATUS, &an_complete);
1539         bnx2x_cl45_read(bp, port,
1540                       ext_phy_type,
1541                       ext_phy_addr,
1542                       MDIO_AN_DEVAD,
1543                       MDIO_AN_REG_STATUS, &an_complete);
1544
1545         if (an_complete & MDIO_AN_REG_STATUS_AN_COMPLETE) {
1546                 ret = 1;
1547                 bnx2x_cl45_read(bp, port,
1548                               ext_phy_type,
1549                               ext_phy_addr,
1550                               MDIO_AN_DEVAD,
1551                               MDIO_AN_REG_ADV_PAUSE, &ld_pause);
1552                 bnx2x_cl45_read(bp, port,
1553                               ext_phy_type,
1554                               ext_phy_addr,
1555                               MDIO_AN_DEVAD,
1556                               MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
1557                 pause_result = (ld_pause &
1558                                 MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
1559                 pause_result |= (lp_pause &
1560                                  MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
1561                 DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x \n",
1562                    pause_result);
1563                 bnx2x_pause_resolve(vars, pause_result);
1564                 if (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE &&
1565                      ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
1566                         bnx2x_cl45_read(bp, port,
1567                                       ext_phy_type,
1568                                       ext_phy_addr,
1569                                       MDIO_AN_DEVAD,
1570                                       MDIO_AN_REG_CL37_FC_LD, &ld_pause);
1571
1572                         bnx2x_cl45_read(bp, port,
1573                                       ext_phy_type,
1574                                       ext_phy_addr,
1575                                       MDIO_AN_DEVAD,
1576                                       MDIO_AN_REG_CL37_FC_LP, &lp_pause);
1577                         pause_result = (ld_pause &
1578                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
1579                         pause_result |= (lp_pause &
1580                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
1581
1582                         bnx2x_pause_resolve(vars, pause_result);
1583                         DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x \n",
1584                                  pause_result);
1585                 }
1586         }
1587         return ret;
1588 }
1589
1590
1591 static void bnx2x_flow_ctrl_resolve(struct link_params *params,
1592                                   struct link_vars *vars,
1593                                   u32 gp_status)
1594 {
1595         struct bnx2x *bp = params->bp;
1596         u16 ld_pause;   /* local driver */
1597         u16 lp_pause;   /* link partner */
1598         u16 pause_result;
1599
1600         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1601
1602         /* resolve from gp_status in case of AN complete and not sgmii */
1603         if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
1604             (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
1605             (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
1606             (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1607              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) {
1608                 CL45_RD_OVER_CL22(bp, params->port,
1609                                       params->phy_addr,
1610                                       MDIO_REG_BANK_COMBO_IEEE0,
1611                                       MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
1612                                       &ld_pause);
1613                 CL45_RD_OVER_CL22(bp, params->port,
1614                                       params->phy_addr,
1615                         MDIO_REG_BANK_COMBO_IEEE0,
1616                         MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
1617                         &lp_pause);
1618                 pause_result = (ld_pause &
1619                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
1620                 pause_result |= (lp_pause &
1621                                  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
1622                 DP(NETIF_MSG_LINK, "pause_result 0x%x\n", pause_result);
1623                 bnx2x_pause_resolve(vars, pause_result);
1624         } else if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
1625                    (bnx2x_ext_phy_resove_fc(params, vars))) {
1626                 return;
1627         } else {
1628                 if (params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO)
1629                         vars->flow_ctrl = params->req_fc_auto_adv;
1630                 else
1631                         vars->flow_ctrl = params->req_flow_ctrl;
1632         }
1633         DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
1634 }
1635
1636
1637 static u8 bnx2x_link_settings_status(struct link_params *params,
1638                                       struct link_vars *vars,
1639                                       u32 gp_status)
1640 {
1641         struct bnx2x *bp = params->bp;
1642         u16 new_line_speed;
1643         u8 rc = 0;
1644         vars->link_status = 0;
1645
1646         if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
1647                 DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n",
1648                          gp_status);
1649
1650                 vars->phy_link_up = 1;
1651                 vars->link_status |= LINK_STATUS_LINK_UP;
1652
1653                 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
1654                         vars->duplex = DUPLEX_FULL;
1655                 else
1656                         vars->duplex = DUPLEX_HALF;
1657
1658                 bnx2x_flow_ctrl_resolve(params, vars, gp_status);
1659
1660                 switch (gp_status & GP_STATUS_SPEED_MASK) {
1661                 case GP_STATUS_10M:
1662                         new_line_speed = SPEED_10;
1663                         if (vars->duplex == DUPLEX_FULL)
1664                                 vars->link_status |= LINK_10TFD;
1665                         else
1666                                 vars->link_status |= LINK_10THD;
1667                         break;
1668
1669                 case GP_STATUS_100M:
1670                         new_line_speed = SPEED_100;
1671                         if (vars->duplex == DUPLEX_FULL)
1672                                 vars->link_status |= LINK_100TXFD;
1673                         else
1674                                 vars->link_status |= LINK_100TXHD;
1675                         break;
1676
1677                 case GP_STATUS_1G:
1678                 case GP_STATUS_1G_KX:
1679                         new_line_speed = SPEED_1000;
1680                         if (vars->duplex == DUPLEX_FULL)
1681                                 vars->link_status |= LINK_1000TFD;
1682                         else
1683                                 vars->link_status |= LINK_1000THD;
1684                         break;
1685
1686                 case GP_STATUS_2_5G:
1687                         new_line_speed = SPEED_2500;
1688                         if (vars->duplex == DUPLEX_FULL)
1689                                 vars->link_status |= LINK_2500TFD;
1690                         else
1691                                 vars->link_status |= LINK_2500THD;
1692                         break;
1693
1694                 case GP_STATUS_5G:
1695                 case GP_STATUS_6G:
1696                         DP(NETIF_MSG_LINK,
1697                                  "link speed unsupported  gp_status 0x%x\n",
1698                                   gp_status);
1699                         return -EINVAL;
1700                         break;
1701                 case GP_STATUS_10G_KX4:
1702                 case GP_STATUS_10G_HIG:
1703                 case GP_STATUS_10G_CX4:
1704                         new_line_speed = SPEED_10000;
1705                         vars->link_status |= LINK_10GTFD;
1706                         break;
1707
1708                 case GP_STATUS_12G_HIG:
1709                         new_line_speed = SPEED_12000;
1710                         vars->link_status |= LINK_12GTFD;
1711                         break;
1712
1713                 case GP_STATUS_12_5G:
1714                         new_line_speed = SPEED_12500;
1715                         vars->link_status |= LINK_12_5GTFD;
1716                         break;
1717
1718                 case GP_STATUS_13G:
1719                         new_line_speed = SPEED_13000;
1720                         vars->link_status |= LINK_13GTFD;
1721                         break;
1722
1723                 case GP_STATUS_15G:
1724                         new_line_speed = SPEED_15000;
1725                         vars->link_status |= LINK_15GTFD;
1726                         break;
1727
1728                 case GP_STATUS_16G:
1729                         new_line_speed = SPEED_16000;
1730                         vars->link_status |= LINK_16GTFD;
1731                         break;
1732
1733                 default:
1734                         DP(NETIF_MSG_LINK,
1735                                   "link speed unsupported gp_status 0x%x\n",
1736                                   gp_status);
1737                 return -EINVAL;
1738                         break;
1739                 }
1740
1741                 /* Upon link speed change set the NIG into drain mode.
1742                 Comes to deals with possible FIFO glitch due to clk change
1743                 when speed is decreased without link down indicator */
1744                 if (new_line_speed != vars->line_speed) {
1745                         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
1746                                     + params->port*4, 0);
1747                         msleep(1);
1748                 }
1749                 vars->line_speed = new_line_speed;
1750                 vars->link_status |= LINK_STATUS_SERDES_LINK;
1751
1752                 if ((params->req_line_speed == SPEED_AUTO_NEG) &&
1753                     ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1754                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
1755                     (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1756                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
1757                     (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1758                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726))) {
1759                         vars->autoneg = AUTO_NEG_ENABLED;
1760
1761                         if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
1762                                 vars->autoneg |= AUTO_NEG_COMPLETE;
1763                                 vars->link_status |=
1764                                         LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
1765                         }
1766
1767                         vars->autoneg |= AUTO_NEG_PARALLEL_DETECTION_USED;
1768                         vars->link_status |=
1769                                 LINK_STATUS_PARALLEL_DETECTION_USED;
1770
1771                 }
1772                 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
1773                         vars->link_status |=
1774                                 LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
1775
1776                 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
1777                         vars->link_status |=
1778                                 LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
1779
1780         } else { /* link_down */
1781                 DP(NETIF_MSG_LINK, "phy link down\n");
1782
1783                 vars->phy_link_up = 0;
1784
1785                 vars->duplex = DUPLEX_FULL;
1786                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1787                 vars->autoneg = AUTO_NEG_DISABLED;
1788                 vars->mac_type = MAC_TYPE_NONE;
1789         }
1790
1791         DP(NETIF_MSG_LINK, "gp_status 0x%x  phy_link_up %x line_speed %x \n",
1792                  gp_status, vars->phy_link_up, vars->line_speed);
1793         DP(NETIF_MSG_LINK, "duplex %x  flow_ctrl 0x%x"
1794                  " autoneg 0x%x\n",
1795                  vars->duplex,
1796                  vars->flow_ctrl, vars->autoneg);
1797         DP(NETIF_MSG_LINK, "link_status 0x%x\n", vars->link_status);
1798
1799         return rc;
1800 }
1801
1802 static void bnx2x_set_sgmii_tx_driver(struct link_params *params)
1803 {
1804         struct bnx2x *bp = params->bp;
1805         u16 lp_up2;
1806         u16 tx_driver;
1807
1808         /* read precomp */
1809
1810         CL45_RD_OVER_CL22(bp, params->port,
1811                               params->phy_addr,
1812                               MDIO_REG_BANK_OVER_1G,
1813                               MDIO_OVER_1G_LP_UP2, &lp_up2);
1814
1815         CL45_RD_OVER_CL22(bp, params->port,
1816                               params->phy_addr,
1817                               MDIO_REG_BANK_TX0,
1818                               MDIO_TX0_TX_DRIVER, &tx_driver);
1819
1820         /* bits [10:7] at lp_up2, positioned at [15:12] */
1821         lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
1822                    MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
1823                   MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
1824
1825         if ((lp_up2 != 0) &&
1826             (lp_up2 != (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK))) {
1827                 /* replace tx_driver bits [15:12] */
1828                 tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
1829                 tx_driver |= lp_up2;
1830                 CL45_WR_OVER_CL22(bp, params->port,
1831                                       params->phy_addr,
1832                                       MDIO_REG_BANK_TX0,
1833                                       MDIO_TX0_TX_DRIVER, tx_driver);
1834         }
1835 }
1836
1837 static u8 bnx2x_emac_program(struct link_params *params,
1838                            u32 line_speed, u32 duplex)
1839 {
1840         struct bnx2x *bp = params->bp;
1841         u8 port = params->port;
1842         u16 mode = 0;
1843
1844         DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
1845         bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
1846                      EMAC_REG_EMAC_MODE,
1847                      (EMAC_MODE_25G_MODE |
1848                      EMAC_MODE_PORT_MII_10M |
1849                      EMAC_MODE_HALF_DUPLEX));
1850         switch (line_speed) {
1851         case SPEED_10:
1852                 mode |= EMAC_MODE_PORT_MII_10M;
1853                 break;
1854
1855         case SPEED_100:
1856                 mode |= EMAC_MODE_PORT_MII;
1857                 break;
1858
1859         case SPEED_1000:
1860                 mode |= EMAC_MODE_PORT_GMII;
1861                 break;
1862
1863         case SPEED_2500:
1864                 mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
1865                 break;
1866
1867         default:
1868                 /* 10G not valid for EMAC */
1869                 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", line_speed);
1870                 return -EINVAL;
1871         }
1872
1873         if (duplex == DUPLEX_HALF)
1874                 mode |= EMAC_MODE_HALF_DUPLEX;
1875         bnx2x_bits_en(bp,
1876                     GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
1877                     mode);
1878
1879         bnx2x_set_led(bp, params->port, LED_MODE_OPER,
1880                     line_speed, params->hw_led_mode, params->chip_id);
1881         return 0;
1882 }
1883
1884 /*****************************************************************************/
1885 /*                           External Phy section                            */
1886 /*****************************************************************************/
1887 static void bnx2x_hw_reset(struct bnx2x *bp, u8 port)
1888 {
1889         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1890                        MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
1891         msleep(1);
1892         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1893                       MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
1894 }
1895
1896 static void bnx2x_ext_phy_reset(struct link_params *params,
1897                               struct link_vars   *vars)
1898 {
1899         struct bnx2x *bp = params->bp;
1900         u32 ext_phy_type;
1901         u8 ext_phy_addr = ((params->ext_phy_config &
1902                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1903                            PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1904         DP(NETIF_MSG_LINK, "Port %x: bnx2x_ext_phy_reset\n", params->port);
1905         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1906         /* The PHY reset is controled by GPIO 1
1907          * Give it 1ms of reset pulse
1908          */
1909         if (vars->phy_flags & PHY_XGXS_FLAG) {
1910
1911                 switch (ext_phy_type) {
1912                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
1913                         DP(NETIF_MSG_LINK, "XGXS Direct\n");
1914                         break;
1915
1916                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
1917                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
1918                         DP(NETIF_MSG_LINK, "XGXS 8705/8706\n");
1919
1920                         /* Restore normal power mode*/
1921                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1922                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1923                                           params->port);
1924
1925                         /* HW reset */
1926                         bnx2x_hw_reset(bp, params->port);
1927
1928                         bnx2x_cl45_write(bp, params->port,
1929                                        ext_phy_type,
1930                                        ext_phy_addr,
1931                                        MDIO_PMA_DEVAD,
1932                                        MDIO_PMA_REG_CTRL, 0xa040);
1933                         break;
1934                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
1935
1936                         /* Restore normal power mode*/
1937                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1938                                           MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1939                                           params->port);
1940
1941                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1942                                           MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1943                                           params->port);
1944
1945                         bnx2x_cl45_write(bp, params->port,
1946                                        ext_phy_type,
1947                                        ext_phy_addr,
1948                                        MDIO_PMA_DEVAD,
1949                                        MDIO_PMA_REG_CTRL,
1950                                        1<<15);
1951
1952                         break;
1953                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
1954                         /* Unset Low Power Mode and SW reset */
1955                         /* Restore normal power mode*/
1956                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1957                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1958                                           params->port);
1959
1960                         DP(NETIF_MSG_LINK, "XGXS 8072\n");
1961                         bnx2x_cl45_write(bp, params->port,
1962                                        ext_phy_type,
1963                                        ext_phy_addr,
1964                                        MDIO_PMA_DEVAD,
1965                                        MDIO_PMA_REG_CTRL,
1966                                        1<<15);
1967                         break;
1968                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
1969                         {
1970                         u16 emac_base;
1971                         emac_base = (params->port) ? GRCBASE_EMAC0 :
1972                                         GRCBASE_EMAC1;
1973
1974                         /* Restore normal power mode*/
1975                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1976                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1977                                           params->port);
1978
1979                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1980                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1981                                           params->port);
1982
1983                         DP(NETIF_MSG_LINK, "XGXS 8073\n");
1984                         }
1985                         break;
1986
1987                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
1988                         DP(NETIF_MSG_LINK, "XGXS SFX7101\n");
1989
1990                         /* Restore normal power mode*/
1991                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1992                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1993                                           params->port);
1994
1995                         /* HW reset */
1996                         bnx2x_hw_reset(bp, params->port);
1997
1998                         break;
1999
2000                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
2001                         DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n");
2002                         break;
2003
2004                 default:
2005                         DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
2006                            params->ext_phy_config);
2007                         break;
2008                 }
2009
2010         } else { /* SerDes */
2011                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
2012                 switch (ext_phy_type) {
2013                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
2014                         DP(NETIF_MSG_LINK, "SerDes Direct\n");
2015                         break;
2016
2017                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
2018                         DP(NETIF_MSG_LINK, "SerDes 5482\n");
2019                         bnx2x_hw_reset(bp, params->port);
2020                         break;
2021
2022                 default:
2023                         DP(NETIF_MSG_LINK,
2024                                  "BAD SerDes ext_phy_config 0x%x\n",
2025                                  params->ext_phy_config);
2026                         break;
2027                 }
2028         }
2029 }
2030
2031 static void bnx2x_bcm8072_external_rom_boot(struct link_params *params)
2032 {
2033         struct bnx2x *bp = params->bp;
2034         u8 port = params->port;
2035         u8 ext_phy_addr = ((params->ext_phy_config &
2036                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2037                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2038         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2039         u16 fw_ver1, fw_ver2;
2040
2041         /* Need to wait 200ms after reset */
2042         msleep(200);
2043         /* Boot port from external ROM
2044          * Set ser_boot_ctl bit in the MISC_CTRL1 register
2045          */
2046         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2047                             MDIO_PMA_DEVAD,
2048                             MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2049
2050         /* Reset internal microprocessor */
2051         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2052                           MDIO_PMA_DEVAD,
2053                           MDIO_PMA_REG_GEN_CTRL,
2054                           MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2055         /* set micro reset = 0 */
2056         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2057                             MDIO_PMA_DEVAD,
2058                             MDIO_PMA_REG_GEN_CTRL,
2059                             MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2060         /* Reset internal microprocessor */
2061         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2062                           MDIO_PMA_DEVAD,
2063                           MDIO_PMA_REG_GEN_CTRL,
2064                           MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2065         /* wait for 100ms for code download via SPI port */
2066         msleep(100);
2067
2068         /* Clear ser_boot_ctl bit */
2069         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2070                             MDIO_PMA_DEVAD,
2071                             MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2072         /* Wait 100ms */
2073         msleep(100);
2074
2075         /* Print the PHY FW version */
2076         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2077                             MDIO_PMA_DEVAD,
2078                             MDIO_PMA_REG_ROM_VER1, &fw_ver1);
2079         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2080                             MDIO_PMA_DEVAD,
2081                             MDIO_PMA_REG_ROM_VER2, &fw_ver2);
2082         DP(NETIF_MSG_LINK, "8072 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
2083 }
2084
2085 static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
2086 {
2087         /* This is only required for 8073A1, version 102 only */
2088
2089         struct bnx2x *bp = params->bp;
2090         u8 ext_phy_addr = ((params->ext_phy_config &
2091                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2092                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2093         u16 val;
2094
2095         /* Read 8073 HW revision*/
2096         bnx2x_cl45_read(bp, params->port,
2097                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2098                       ext_phy_addr,
2099                       MDIO_PMA_DEVAD,
2100                       0xc801, &val);
2101
2102         if (val != 1) {
2103                 /* No need to workaround in 8073 A1 */
2104                 return 0;
2105         }
2106
2107         bnx2x_cl45_read(bp, params->port,
2108                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2109                       ext_phy_addr,
2110                       MDIO_PMA_DEVAD,
2111                       MDIO_PMA_REG_ROM_VER2, &val);
2112
2113         /* SNR should be applied only for version 0x102 */
2114         if (val != 0x102)
2115                 return 0;
2116
2117         return 1;
2118 }
2119
2120 static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
2121 {
2122         struct bnx2x *bp = params->bp;
2123         u8 ext_phy_addr = ((params->ext_phy_config &
2124                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2125                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2126         u16 val, cnt, cnt1 ;
2127
2128         bnx2x_cl45_read(bp, params->port,
2129                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2130                       ext_phy_addr,
2131                       MDIO_PMA_DEVAD,
2132                       0xc801, &val);
2133
2134         if (val > 0) {
2135                 /* No need to workaround in 8073 A1 */
2136                 return 0;
2137         }
2138         /* XAUI workaround in 8073 A0: */
2139
2140         /* After loading the boot ROM and restarting Autoneg,
2141         poll Dev1, Reg $C820: */
2142
2143         for (cnt = 0; cnt < 1000; cnt++) {
2144                 bnx2x_cl45_read(bp, params->port,
2145                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2146                               ext_phy_addr,
2147                               MDIO_PMA_DEVAD,
2148                               0xc820, &val);
2149                   /* If bit [14] = 0 or bit [13] = 0, continue on with
2150                    system initialization (XAUI work-around not required,
2151                     as these bits indicate 2.5G or 1G link up). */
2152                 if (!(val & (1<<14)) || !(val & (1<<13))) {
2153                         DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
2154                         return 0;
2155                 } else if (!(val & (1<<15))) {
2156                         DP(NETIF_MSG_LINK, "clc bit 15 went off\n");
2157                          /* If bit 15 is 0, then poll Dev1, Reg $C841 until
2158                           it's MSB (bit 15) goes to 1 (indicating that the
2159                           XAUI workaround has completed),
2160                           then continue on with system initialization.*/
2161                         for (cnt1 = 0; cnt1 < 1000; cnt1++) {
2162                                 bnx2x_cl45_read(bp, params->port,
2163                                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2164                                         ext_phy_addr,
2165                                         MDIO_PMA_DEVAD,
2166                                         0xc841, &val);
2167                                 if (val & (1<<15)) {
2168                                         DP(NETIF_MSG_LINK,
2169                                           "XAUI workaround has completed\n");
2170                                         return 0;
2171                                  }
2172                                  msleep(3);
2173                         }
2174                         break;
2175                 }
2176                 msleep(3);
2177         }
2178         DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
2179         return -EINVAL;
2180
2181 }
2182
2183 static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port,
2184                                           u8 ext_phy_addr)
2185 {
2186         u16 fw_ver1, fw_ver2;
2187         /* Boot port from external ROM  */
2188         /* EDC grst */
2189         bnx2x_cl45_write(bp, port,
2190                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2191                        ext_phy_addr,
2192                        MDIO_PMA_DEVAD,
2193                        MDIO_PMA_REG_GEN_CTRL,
2194                        0x0001);
2195
2196         /* ucode reboot and rst */
2197         bnx2x_cl45_write(bp, port,
2198                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2199                        ext_phy_addr,
2200                        MDIO_PMA_DEVAD,
2201                        MDIO_PMA_REG_GEN_CTRL,
2202                        0x008c);
2203
2204         bnx2x_cl45_write(bp, port,
2205                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2206                        ext_phy_addr,
2207                        MDIO_PMA_DEVAD,
2208                        MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2209
2210         /* Reset internal microprocessor */
2211         bnx2x_cl45_write(bp, port,
2212                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2213                        ext_phy_addr,
2214                        MDIO_PMA_DEVAD,
2215                        MDIO_PMA_REG_GEN_CTRL,
2216                        MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2217
2218         /* Release srst bit */
2219         bnx2x_cl45_write(bp, port,
2220                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2221                        ext_phy_addr,
2222                        MDIO_PMA_DEVAD,
2223                        MDIO_PMA_REG_GEN_CTRL,
2224                        MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2225
2226         /* wait for 100ms for code download via SPI port */
2227         msleep(100);
2228
2229         /* Clear ser_boot_ctl bit */
2230         bnx2x_cl45_write(bp, port,
2231                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2232                        ext_phy_addr,
2233                        MDIO_PMA_DEVAD,
2234                        MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2235
2236         bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2237                       ext_phy_addr,
2238                       MDIO_PMA_DEVAD,
2239                       MDIO_PMA_REG_ROM_VER1, &fw_ver1);
2240         bnx2x_cl45_read(bp, port,
2241                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2242                       ext_phy_addr,
2243                       MDIO_PMA_DEVAD,
2244                       MDIO_PMA_REG_ROM_VER2, &fw_ver2);
2245         DP(NETIF_MSG_LINK, "8073 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
2246
2247 }
2248
2249 static void bnx2x_bcm8726_external_rom_boot(struct link_params *params)
2250 {
2251         struct bnx2x *bp = params->bp;
2252         u8 port = params->port;
2253         u8 ext_phy_addr = ((params->ext_phy_config &
2254                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2255                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2256         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2257
2258         /* Need to wait 100ms after reset */
2259         msleep(100);
2260
2261         /* Set serial boot control for external load */
2262         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2263                        MDIO_PMA_DEVAD,
2264                        MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2265
2266         /* Micro controller re-boot */
2267         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2268                        MDIO_PMA_DEVAD,
2269                        MDIO_PMA_REG_GEN_CTRL,
2270                        MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2271
2272         /* Set soft reset */
2273         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2274                        MDIO_PMA_DEVAD,
2275                        MDIO_PMA_REG_GEN_CTRL,
2276                        MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2277
2278         /* Clear soft reset.
2279         Will automatically reset micro-controller re-boot */
2280         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2281                        MDIO_PMA_DEVAD,
2282                        MDIO_PMA_REG_GEN_CTRL,
2283                        MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2284
2285         /* wait for 100ms for microcode load */
2286         msleep(100);
2287
2288         /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
2289         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2290                        MDIO_PMA_DEVAD,
2291                        MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2292
2293         msleep(200);
2294 }
2295
2296 static void bnx2x_bcm8726_set_transmitter(struct bnx2x *bp, u8 port,
2297                                         u8 ext_phy_addr, u8 tx_en)
2298 {
2299         u16 val;
2300         DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n",
2301                  tx_en, port);
2302         /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
2303         bnx2x_cl45_read(bp, port,
2304                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2305                       ext_phy_addr,
2306                       MDIO_PMA_DEVAD,
2307                       MDIO_PMA_REG_PHY_IDENTIFIER,
2308                       &val);
2309
2310         if (tx_en)
2311                 val &= ~(1<<15);
2312         else
2313                 val |= (1<<15);
2314
2315         bnx2x_cl45_write(bp, port,
2316                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2317                        ext_phy_addr,
2318                        MDIO_PMA_DEVAD,
2319                        MDIO_PMA_REG_PHY_IDENTIFIER,
2320                        val);
2321 }
2322
2323
2324 static u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr,
2325                                      u8 byte_cnt, u8 *o_buf) {
2326         struct bnx2x *bp = params->bp;
2327         u16 val, i;
2328         u8 port = params->port;
2329         u8 ext_phy_addr = ((params->ext_phy_config &
2330                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2331                            PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2332         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2333         if (byte_cnt > 16) {
2334                 DP(NETIF_MSG_LINK, "Reading from eeprom is"
2335                             " is limited to 0xf\n");
2336                 return -EINVAL;
2337         }
2338         /* Set the read command byte count */
2339         bnx2x_cl45_write(bp, port,
2340                        ext_phy_type,
2341                        ext_phy_addr,
2342                        MDIO_PMA_DEVAD,
2343                        MDIO_PMA_REG_8726_TWO_WIRE_BYTE_CNT,
2344                        (byte_cnt | 0xa000));
2345
2346         /* Set the read command address */
2347         bnx2x_cl45_write(bp, port,
2348                        ext_phy_type,
2349                        ext_phy_addr,
2350                        MDIO_PMA_DEVAD,
2351                        MDIO_PMA_REG_8726_TWO_WIRE_MEM_ADDR,
2352                        addr);
2353
2354         /* Activate read command */
2355         bnx2x_cl45_write(bp, port,
2356                        ext_phy_type,
2357                        ext_phy_addr,
2358                        MDIO_PMA_DEVAD,
2359                        MDIO_PMA_REG_8726_TWO_WIRE_CTRL,
2360                        0x2c0f);
2361
2362         /* Wait up to 500us for command complete status */
2363         for (i = 0; i < 100; i++) {
2364                 bnx2x_cl45_read(bp, port,
2365                               ext_phy_type,
2366                               ext_phy_addr,
2367                               MDIO_PMA_DEVAD,
2368                               MDIO_PMA_REG_8726_TWO_WIRE_CTRL, &val);
2369                 if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) ==
2370                     MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE)
2371                         break;
2372                 udelay(5);
2373         }
2374
2375         if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) !=
2376                     MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE) {
2377                 DP(NETIF_MSG_LINK,
2378                          "Got bad status 0x%x when reading from SFP+ EEPROM\n",
2379                          (val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK));
2380                 return -EINVAL;
2381         }
2382
2383         /* Read the buffer */
2384         for (i = 0; i < byte_cnt; i++) {
2385                 bnx2x_cl45_read(bp, port,
2386                               ext_phy_type,
2387                               ext_phy_addr,
2388                               MDIO_PMA_DEVAD,
2389                               MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
2390                 o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
2391         }
2392
2393         for (i = 0; i < 100; i++) {
2394                 bnx2x_cl45_read(bp, port,
2395                               ext_phy_type,
2396                               ext_phy_addr,
2397                               MDIO_PMA_DEVAD,
2398                               MDIO_PMA_REG_8726_TWO_WIRE_CTRL, &val);
2399                 if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) ==
2400                     MDIO_PMA_REG_8726_TWO_WIRE_STATUS_IDLE)
2401                         return 0;;
2402                 msleep(1);
2403         }
2404         return -EINVAL;
2405 }
2406
2407
2408 static u8 bnx2x_get_sfp_module_type(struct link_params *params,
2409                                   u8 *module_type)
2410 {
2411         struct bnx2x *bp = params->bp;
2412         u8 val;
2413         *module_type = SFP_MODULE_TYPE_UNKNOWN;
2414
2415         /* First check for copper cable */
2416         if (bnx2x_read_sfp_module_eeprom(params,
2417                                        SFP_EEPROM_CON_TYPE_ADDR,
2418                                        1,
2419                                        &val) != 0) {
2420                 DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM");
2421                 return -EINVAL;
2422         }
2423
2424         switch (val) {
2425         case SFP_EEPROM_CON_TYPE_VAL_COPPER:
2426         {
2427                 u8 copper_module_type;
2428                 /* Check if its active cable( includes SFP+ module)
2429                 of passive cable*/
2430                 if (bnx2x_read_sfp_module_eeprom(params,
2431                                                SFP_EEPROM_FC_TX_TECH_ADDR,
2432                                                1,
2433                                                &copper_module_type) !=
2434                     0) {
2435                         DP(NETIF_MSG_LINK,
2436                                 "Failed to read copper-cable-type"
2437                                 " from SFP+ EEPROM\n");
2438                         return -EINVAL;
2439                 }
2440
2441                 if (copper_module_type &
2442                     SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
2443                         DP(NETIF_MSG_LINK, "Active Copper cable detected\n");
2444                         *module_type = SFP_MODULE_TYPE_ACTIVE_COPPER_CABLE;
2445                 } else if (copper_module_type &
2446                         SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
2447                                 DP(NETIF_MSG_LINK, "Passive Copper"
2448                                             " cable detected\n");
2449                                 *module_type =
2450                                       SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE;
2451                 } else {
2452                         DP(NETIF_MSG_LINK, "Unknown copper-cable-"
2453                                      "type 0x%x !!!\n", copper_module_type);
2454                         return -EINVAL;
2455                 }
2456                 break;
2457         }
2458         case SFP_EEPROM_CON_TYPE_VAL_LC:
2459                 DP(NETIF_MSG_LINK, "Optic module detected\n");
2460                 *module_type = SFP_MODULE_TYPE_LC;
2461                 break;
2462
2463         default:
2464                 DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n",
2465                          val);
2466                 return -EINVAL;
2467         }
2468         return 0;
2469 }
2470
2471
2472 /* This function read the relevant field from the module ( SFP+ ),
2473         and verify it is compliant with this board */
2474 static u8 bnx2x_verify_sfp_module(struct link_params *params,
2475                                 u8 module_type)
2476 {
2477         struct bnx2x *bp = params->bp;
2478         u8 *str_p, *tmp_buf;
2479         u16 i;
2480
2481 #define COMPLIANCE_STR_CNT 6
2482         u8 *compliance_str[] = {"Broadcom", "JDSU", "Molex Inc", "PICOLIGHT",
2483                 "FINISAR CORP.   ", "Amphenol"};
2484         u8 buf[SFP_EEPROM_VENDOR_NAME_SIZE];
2485         /* Passive Copper cables are allowed to participate,
2486         since the module is hardwired to the copper cable */
2487
2488         if (!(params->feature_config_flags &
2489              FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED)) {
2490                 DP(NETIF_MSG_LINK, "NOT enforcing module verification\n");
2491                 return 0;
2492         }
2493
2494         if (module_type != SFP_MODULE_TYPE_LC) {
2495                 DP(NETIF_MSG_LINK, "No need to verify copper cable\n");
2496                 return 0;
2497         }
2498
2499         /* In case of non copper cable or Active copper cable,
2500                 verify that the SFP+ module is compliant with this board*/
2501         if (bnx2x_read_sfp_module_eeprom(params,
2502                                        SFP_EEPROM_VENDOR_NAME_ADDR,
2503                                        SFP_EEPROM_VENDOR_NAME_SIZE,
2504                                        buf) != 0) {
2505                 DP(NETIF_MSG_LINK, "Failed to read Vendor-Name from"
2506                             " module EEPROM\n");
2507                 return -EINVAL;
2508         }
2509         for (i = 0; i < COMPLIANCE_STR_CNT; i++) {
2510                 str_p = compliance_str[i];
2511                 tmp_buf = buf;
2512                 while (*str_p) {
2513                         if ((u8)(*tmp_buf) != (u8)(*str_p))
2514                                 break;
2515                         str_p++;
2516                         tmp_buf++;
2517                 }
2518
2519                 if (!(*str_p)) {
2520                         DP(NETIF_MSG_LINK, "SFP+ Module verified, "
2521                                      "index=%x\n", i);
2522                         return 0;
2523                 }
2524         }
2525         DP(NETIF_MSG_LINK, "Incompliant SFP+ module. Disable module !!!\n");
2526         return -EINVAL;
2527 }
2528
2529
2530 static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params,
2531                                         u8 module_type)
2532 {
2533         struct bnx2x *bp = params->bp;
2534         u8 port = params->port;
2535         u8 options[SFP_EEPROM_OPTIONS_SIZE];
2536         u8 limiting_mode;
2537         u8 ext_phy_addr = ((params->ext_phy_config &
2538                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2539                            PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2540
2541         if (bnx2x_read_sfp_module_eeprom(params,
2542                                        SFP_EEPROM_OPTIONS_ADDR,
2543                                        SFP_EEPROM_OPTIONS_SIZE,
2544                                        options) != 0) {
2545                 DP(NETIF_MSG_LINK, "Failed to read Option field from"
2546                             " module EEPROM\n");
2547                 return -EINVAL;
2548         }
2549         limiting_mode = !(options[0] &
2550                           SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK);
2551         if (limiting_mode &&
2552             (module_type != SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE)) {
2553                 DP(NETIF_MSG_LINK,
2554                          "Module options = 0x%x.Setting LIMITING MODE\n",
2555                          options[0]);
2556                 bnx2x_cl45_write(bp, port,
2557                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2558                                ext_phy_addr,
2559                                MDIO_PMA_DEVAD,
2560                                MDIO_PMA_REG_ROM_VER2,
2561                                SFP_LIMITING_MODE_VALUE);
2562         } else { /* LRM mode ( default )*/
2563                 u16 cur_limiting_mode;
2564                 DP(NETIF_MSG_LINK, "Module options = 0x%x.Setting LRM MODE\n",
2565                          options[0]);
2566
2567                 bnx2x_cl45_read(bp, port,
2568                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2569                                ext_phy_addr,
2570                                MDIO_PMA_DEVAD,
2571                                MDIO_PMA_REG_ROM_VER2,
2572                                &cur_limiting_mode);
2573
2574                 /* Changing to LRM mode takes quite few seconds.
2575                 So do it only if current mode is limiting
2576                 ( default is LRM )*/
2577                 if (cur_limiting_mode != SFP_LIMITING_MODE_VALUE)
2578                         return 0;
2579
2580                 bnx2x_cl45_write(bp, port,
2581                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2582                                ext_phy_addr,
2583                                MDIO_PMA_DEVAD,
2584                                MDIO_PMA_REG_LRM_MODE,
2585                                0);
2586                 bnx2x_cl45_write(bp, port,
2587                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2588                                ext_phy_addr,
2589                                MDIO_PMA_DEVAD,
2590                                MDIO_PMA_REG_ROM_VER2,
2591                                0x128);
2592                 bnx2x_cl45_write(bp, port,
2593                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2594                                ext_phy_addr,
2595                                MDIO_PMA_DEVAD,
2596                                MDIO_PMA_REG_MISC_CTRL0,
2597                                0x4008);
2598                 bnx2x_cl45_write(bp, port,
2599                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2600                                ext_phy_addr,
2601                                MDIO_PMA_DEVAD,
2602                                MDIO_PMA_REG_LRM_MODE,
2603                                0xaaaa);
2604         }
2605         return 0;
2606 }
2607
2608 static u8 bnx2x_wait_for_sfp_module_initialized(struct link_params *params)
2609 {
2610         u8 val;
2611         struct bnx2x *bp = params->bp;
2612         u16 timeout;
2613         /* Initialization time after hot-plug may take up to 300ms for some
2614         phys type ( e.g. JDSU ) */
2615         for (timeout = 0; timeout < 60; timeout++) {
2616                 if (bnx2x_read_sfp_module_eeprom(params, 1, 1, &val)
2617                     == 0) {
2618                         DP(NETIF_MSG_LINK, "SFP+ module initialization "
2619                                      "took %d ms\n", timeout * 5);
2620                         return 0;
2621                 }
2622                 msleep(5);
2623         }
2624         return -EINVAL;
2625 }
2626
2627 static u8 bnx2x_sfp_module_detection(struct link_params *params)
2628 {
2629         struct bnx2x *bp = params->bp;
2630         u8 module_type;
2631         u8 ext_phy_addr = ((params->ext_phy_config &
2632                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2633                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2634         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2635
2636         if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
2637                 DP(NETIF_MSG_LINK, "Module detection is not required "
2638                             "for this phy\n");
2639                 return 0;
2640         }
2641
2642         DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
2643                  params->port);
2644
2645         if (bnx2x_get_sfp_module_type(params,
2646                                     &module_type) != 0) {
2647                 DP(NETIF_MSG_LINK, "Failed to get valid module type\n");
2648                 if (!(params->feature_config_flags &
2649                       FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED)) {
2650                         /* In case module detection is disabled, it trys to
2651                         link up. The issue that can happen here is LRM /
2652                         LIMITING mode which set according to the module-type*/
2653                         DP(NETIF_MSG_LINK, "Unable to read module-type."
2654                                     "Probably due to Bit Stretching."
2655                                     " Proceeding...\n");
2656                 } else {
2657                         return -EINVAL;
2658                 }
2659         } else if (bnx2x_verify_sfp_module(params, module_type) !=
2660                    0) {
2661                 /* check SFP+ module compatibility */
2662                 DP(NETIF_MSG_LINK, "Module verification failed!!\n");
2663                 /* Turn on fault module-detected led */
2664                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
2665                                   MISC_REGISTERS_GPIO_HIGH,
2666                                   params->port);
2667                 return -EINVAL;
2668         }
2669
2670         /* Turn off fault module-detected led */
2671         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
2672                           MISC_REGISTERS_GPIO_LOW,
2673                           params->port);
2674
2675         /* Check and set limiting mode / LRM mode */
2676         if (bnx2x_bcm8726_set_limiting_mode(params, module_type)
2677              != 0) {
2678                 DP(NETIF_MSG_LINK, "Setting limiting mode failed!!\n");
2679                 return -EINVAL;
2680         }
2681
2682         /* Enable transmit for this module */
2683         bnx2x_bcm8726_set_transmitter(bp, params->port,
2684                                     ext_phy_addr, 1);
2685         return 0;
2686 }
2687
2688 void bnx2x_handle_module_detect_int(struct link_params *params)
2689 {
2690         struct bnx2x *bp = params->bp;
2691         u32 gpio_val;
2692         u8 port = params->port;
2693         /* Set valid module led off */
2694         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
2695                           MISC_REGISTERS_GPIO_HIGH,
2696                           params->port);
2697
2698         /* Get current gpio val refelecting module plugged in / out*/
2699         gpio_val = bnx2x_get_gpio(bp,  MISC_REGISTERS_GPIO_3, port);
2700
2701         /* Call the handling function in case module is detected */
2702         if (gpio_val == 0) {
2703
2704                 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
2705                                       MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
2706                                       port);
2707
2708                 if (bnx2x_wait_for_sfp_module_initialized(params)
2709                     == 0)
2710                         bnx2x_sfp_module_detection(params);
2711                 else
2712                         DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
2713         } else {
2714                 u8 ext_phy_addr = ((params->ext_phy_config &
2715                                     PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2716                                    PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2717                 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
2718                                       MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
2719                                       port);
2720                 /* Module was plugged out. */
2721                 /* Disable transmit for this module */
2722                 bnx2x_bcm8726_set_transmitter(bp, params->port,
2723                                             ext_phy_addr, 0);
2724         }
2725 }
2726
2727 static void bnx2x_bcm807x_force_10G(struct link_params *params)
2728 {
2729         struct bnx2x *bp = params->bp;
2730         u8 port = params->port;
2731         u8 ext_phy_addr = ((params->ext_phy_config &
2732                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2733                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2734         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2735
2736         /* Force KR or KX */
2737         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2738                        MDIO_PMA_DEVAD,
2739                        MDIO_PMA_REG_CTRL,
2740                        0x2040);
2741         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2742                        MDIO_PMA_DEVAD,
2743                        MDIO_PMA_REG_10G_CTRL2,
2744                        0x000b);
2745         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2746                        MDIO_PMA_DEVAD,
2747                        MDIO_PMA_REG_BCM_CTRL,
2748                        0x0000);
2749         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2750                        MDIO_AN_DEVAD,
2751                        MDIO_AN_REG_CTRL,
2752                        0x0000);
2753 }
2754 static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params)
2755 {
2756         struct bnx2x *bp = params->bp;
2757         u8 port = params->port;
2758         u16 val;
2759         u8 ext_phy_addr = ((params->ext_phy_config &
2760                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2761                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2762         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2763
2764         bnx2x_cl45_read(bp, params->port,
2765                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2766                       ext_phy_addr,
2767                       MDIO_PMA_DEVAD,
2768                       0xc801, &val);
2769
2770         if (val == 0) {
2771                 /* Mustn't set low power mode in 8073 A0 */
2772                 return;
2773         }
2774
2775         /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
2776         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2777                        MDIO_XS_DEVAD,
2778                        MDIO_XS_PLL_SEQUENCER, &val);
2779         val &= ~(1<<13);
2780         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2781                        MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2782
2783         /* PLL controls */
2784         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2785                        MDIO_XS_DEVAD, 0x805E, 0x1077);
2786         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2787                        MDIO_XS_DEVAD, 0x805D, 0x0000);
2788         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2789                        MDIO_XS_DEVAD, 0x805C, 0x030B);
2790         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2791                        MDIO_XS_DEVAD, 0x805B, 0x1240);
2792         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2793                        MDIO_XS_DEVAD, 0x805A, 0x2490);
2794
2795         /* Tx Controls */
2796         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2797                        MDIO_XS_DEVAD, 0x80A7, 0x0C74);
2798         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2799                        MDIO_XS_DEVAD, 0x80A6, 0x9041);
2800         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2801                        MDIO_XS_DEVAD, 0x80A5, 0x4640);
2802
2803         /* Rx Controls */
2804         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2805                        MDIO_XS_DEVAD, 0x80FE, 0x01C4);
2806         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2807                        MDIO_XS_DEVAD, 0x80FD, 0x9249);
2808         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2809                        MDIO_XS_DEVAD, 0x80FC, 0x2015);
2810
2811         /* Enable PLL sequencer  (use read-modify-write to set bit 13) */
2812         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2813                        MDIO_XS_DEVAD,
2814                        MDIO_XS_PLL_SEQUENCER, &val);
2815         val |= (1<<13);
2816         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2817                        MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2818 }
2819
2820 static void bnx2x_8073_set_pause_cl37(struct link_params *params,
2821                                   struct link_vars *vars)
2822 {
2823
2824         struct bnx2x *bp = params->bp;
2825         u16 cl37_val;
2826         u8 ext_phy_addr = ((params->ext_phy_config &
2827                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2828                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2829         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2830
2831         bnx2x_cl45_read(bp, params->port,
2832                       ext_phy_type,
2833                       ext_phy_addr,
2834                       MDIO_AN_DEVAD,
2835                       MDIO_AN_REG_CL37_FC_LD, &cl37_val);
2836
2837         cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2838         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2839
2840         if ((vars->ieee_fc &
2841             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
2842             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
2843                 cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
2844         }
2845         if ((vars->ieee_fc &
2846             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
2847             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
2848                 cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
2849         }
2850         if ((vars->ieee_fc &
2851             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
2852             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
2853                 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2854         }
2855         DP(NETIF_MSG_LINK,
2856                  "Ext phy AN advertize cl37 0x%x\n", cl37_val);
2857
2858         bnx2x_cl45_write(bp, params->port,
2859                        ext_phy_type,
2860                        ext_phy_addr,
2861                        MDIO_AN_DEVAD,
2862                        MDIO_AN_REG_CL37_FC_LD, cl37_val);
2863         msleep(500);
2864 }
2865
2866 static void bnx2x_ext_phy_set_pause(struct link_params *params,
2867                                   struct link_vars *vars)
2868 {
2869         struct bnx2x *bp = params->bp;
2870         u16 val;
2871         u8 ext_phy_addr = ((params->ext_phy_config &
2872                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2873                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2874         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2875
2876         /* read modify write pause advertizing */
2877         bnx2x_cl45_read(bp, params->port,
2878                       ext_phy_type,
2879                       ext_phy_addr,
2880                       MDIO_AN_DEVAD,
2881                       MDIO_AN_REG_ADV_PAUSE, &val);
2882
2883         val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
2884
2885         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2886
2887         if ((vars->ieee_fc &
2888             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
2889             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
2890                 val |=  MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
2891         }
2892         if ((vars->ieee_fc &
2893             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
2894             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
2895                 val |=
2896                  MDIO_AN_REG_ADV_PAUSE_PAUSE;
2897         }
2898         DP(NETIF_MSG_LINK,
2899                  "Ext phy AN advertize 0x%x\n", val);
2900         bnx2x_cl45_write(bp, params->port,
2901                        ext_phy_type,
2902                        ext_phy_addr,
2903                        MDIO_AN_DEVAD,
2904                        MDIO_AN_REG_ADV_PAUSE, val);
2905 }
2906
2907
2908 static void bnx2x_init_internal_phy(struct link_params *params,
2909                                 struct link_vars *vars)
2910 {
2911         struct bnx2x *bp = params->bp;
2912         u8 port = params->port;
2913         if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
2914                 u16 bank, rx_eq;
2915
2916                 rx_eq = ((params->serdes_config &
2917                           PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK) >>
2918                          PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT);
2919
2920                 DP(NETIF_MSG_LINK, "setting rx eq to 0x%x\n", rx_eq);
2921                 for (bank = MDIO_REG_BANK_RX0; bank <= MDIO_REG_BANK_RX_ALL;
2922                       bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0)) {
2923                         CL45_WR_OVER_CL22(bp, port,
2924                                               params->phy_addr,
2925                                               bank ,
2926                                               MDIO_RX0_RX_EQ_BOOST,
2927                                               ((rx_eq &
2928                                 MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK) |
2929                                 MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL));
2930                 }
2931
2932                 /* forced speed requested? */
2933                 if (vars->line_speed != SPEED_AUTO_NEG) {
2934                         DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
2935
2936                         /* disable autoneg */
2937                         bnx2x_set_autoneg(params, vars);
2938
2939                         /* program speed and duplex */
2940                         bnx2x_program_serdes(params, vars);
2941
2942                 } else { /* AN_mode */
2943                         DP(NETIF_MSG_LINK, "not SGMII, AN\n");
2944
2945                         /* AN enabled */
2946                         bnx2x_set_brcm_cl37_advertisment(params);
2947
2948                         /* program duplex & pause advertisement (for aneg) */
2949                         bnx2x_set_ieee_aneg_advertisment(params,
2950                                                        vars->ieee_fc);
2951
2952                         /* enable autoneg */
2953                         bnx2x_set_autoneg(params, vars);
2954
2955                         /* enable and restart AN */
2956                         bnx2x_restart_autoneg(params);
2957                 }
2958
2959         } else { /* SGMII mode */
2960                 DP(NETIF_MSG_LINK, "SGMII\n");
2961
2962                 bnx2x_initialize_sgmii_process(params, vars);
2963         }
2964 }
2965
2966 static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
2967 {
2968         struct bnx2x *bp = params->bp;
2969         u32 ext_phy_type;
2970         u8 ext_phy_addr;
2971         u16 cnt;
2972         u16 ctrl = 0;
2973         u16 val = 0;
2974         u8 rc = 0;
2975         if (vars->phy_flags & PHY_XGXS_FLAG) {
2976                 ext_phy_addr = ((params->ext_phy_config &
2977                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2978                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2979
2980                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2981                 /* Make sure that the soft reset is off (expect for the 8072:
2982                  * due to the lock, it will be done inside the specific
2983                  * handling)
2984                  */
2985                 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
2986                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
2987                    (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) &&
2988                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
2989                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
2990                         /* Wait for soft reset to get cleared upto 1 sec */
2991                         for (cnt = 0; cnt < 1000; cnt++) {
2992                                 bnx2x_cl45_read(bp, params->port,
2993                                               ext_phy_type,
2994                                               ext_phy_addr,
2995                                               MDIO_PMA_DEVAD,
2996                                               MDIO_PMA_REG_CTRL, &ctrl);
2997                                 if (!(ctrl & (1<<15)))
2998                                         break;
2999                                 msleep(1);
3000                         }
3001                         DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n",
3002                                  ctrl, cnt);
3003                 }
3004
3005                 switch (ext_phy_type) {
3006                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
3007                         break;
3008
3009                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
3010                         DP(NETIF_MSG_LINK, "XGXS 8705\n");
3011
3012                         bnx2x_cl45_write(bp, params->port,
3013                                        ext_phy_type,
3014                                        ext_phy_addr,
3015                                        MDIO_PMA_DEVAD,
3016                                        MDIO_PMA_REG_MISC_CTRL,
3017                                        0x8288);
3018                         bnx2x_cl45_write(bp, params->port,
3019                                        ext_phy_type,
3020                                        ext_phy_addr,
3021                                        MDIO_PMA_DEVAD,
3022                                        MDIO_PMA_REG_PHY_IDENTIFIER,
3023                                        0x7fbf);
3024                         bnx2x_cl45_write(bp, params->port,
3025                                        ext_phy_type,
3026                                        ext_phy_addr,
3027                                        MDIO_PMA_DEVAD,
3028                                        MDIO_PMA_REG_CMU_PLL_BYPASS,
3029                                        0x0100);
3030                         bnx2x_cl45_write(bp, params->port,
3031                                        ext_phy_type,
3032                                        ext_phy_addr,
3033                                        MDIO_WIS_DEVAD,
3034                                        MDIO_WIS_REG_LASI_CNTL, 0x1);
3035                         break;
3036
3037                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3038                         DP(NETIF_MSG_LINK, "XGXS 8706\n");
3039
3040                         msleep(10);
3041                         /* Force speed */
3042                         /* First enable LASI */
3043                         bnx2x_cl45_write(bp, params->port,
3044                                        ext_phy_type,
3045                                        ext_phy_addr,
3046                                        MDIO_PMA_DEVAD,
3047                                        MDIO_PMA_REG_RX_ALARM_CTRL,
3048                                        0x0400);
3049                         bnx2x_cl45_write(bp, params->port,
3050                                        ext_phy_type,
3051                                        ext_phy_addr,
3052                                        MDIO_PMA_DEVAD,
3053                                        MDIO_PMA_REG_LASI_CTRL, 0x0004);
3054
3055                         if (params->req_line_speed == SPEED_10000) {
3056                                 DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
3057
3058                                 bnx2x_cl45_write(bp, params->port,
3059                                                ext_phy_type,
3060                                                ext_phy_addr,
3061                                                MDIO_PMA_DEVAD,
3062                                                MDIO_PMA_REG_DIGITAL_CTRL,
3063                                                0x400);
3064                         } else {
3065                                 /* Force 1Gbps using autoneg with 1G
3066                                 advertisment */
3067
3068                                 /* Allow CL37 through CL73 */
3069                                 DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
3070                                 bnx2x_cl45_write(bp, params->port,
3071                                                ext_phy_type,
3072                                                ext_phy_addr,
3073                                                MDIO_AN_DEVAD,
3074                                                MDIO_AN_REG_CL37_CL73,
3075                                                0x040c);
3076
3077                                 /* Enable Full-Duplex advertisment on CL37 */
3078                                 bnx2x_cl45_write(bp, params->port,
3079                                                ext_phy_type,
3080                                                ext_phy_addr,
3081                                                MDIO_AN_DEVAD,
3082                                                MDIO_AN_REG_CL37_FC_LP,
3083                                                0x0020);
3084                                 /* Enable CL37 AN */
3085                                 bnx2x_cl45_write(bp, params->port,
3086                                                ext_phy_type,
3087                                                ext_phy_addr,
3088                                                MDIO_AN_DEVAD,
3089                                                MDIO_AN_REG_CL37_AN,
3090                                                0x1000);
3091                                 /* 1G support */
3092                                 bnx2x_cl45_write(bp, params->port,
3093                                                ext_phy_type,
3094                                                ext_phy_addr,
3095                                                MDIO_AN_DEVAD,
3096                                                MDIO_AN_REG_ADV, (1<<5));
3097
3098                                 /* Enable clause 73 AN */
3099                                 bnx2x_cl45_write(bp, params->port,
3100                                                ext_phy_type,
3101                                                ext_phy_addr,
3102                                                MDIO_AN_DEVAD,
3103                                                MDIO_AN_REG_CTRL,
3104                                                0x1200);
3105
3106                         }
3107
3108                         break;
3109                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
3110                         DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
3111                         bnx2x_bcm8726_external_rom_boot(params);
3112
3113                         /* Need to call module detected on initialization since
3114                         the module detection triggered by actual module
3115                         insertion might occur before driver is loaded, and when
3116                         driver is loaded, it reset all registers, including the
3117                         transmitter */
3118                         bnx2x_sfp_module_detection(params);
3119                         if (params->req_line_speed == SPEED_1000) {
3120                                 DP(NETIF_MSG_LINK, "Setting 1G force\n");
3121                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3122                                                ext_phy_addr, MDIO_PMA_DEVAD,
3123                                                MDIO_PMA_REG_CTRL, 0x40);
3124                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3125                                                ext_phy_addr, MDIO_PMA_DEVAD,
3126                                                MDIO_PMA_REG_10G_CTRL2, 0xD);
3127                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3128                                                ext_phy_addr, MDIO_PMA_DEVAD,
3129                                                MDIO_PMA_REG_LASI_CTRL, 0x5);
3130                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3131                                                ext_phy_addr, MDIO_PMA_DEVAD,
3132                                                MDIO_PMA_REG_RX_ALARM_CTRL,
3133                                                0x400);
3134                         } else if ((params->req_line_speed ==
3135                                     SPEED_AUTO_NEG) &&
3136                                    ((params->speed_cap_mask &
3137                                      PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) {
3138                                 DP(NETIF_MSG_LINK, "Setting 1G clause37 \n");
3139                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3140                                                ext_phy_addr, MDIO_AN_DEVAD,
3141                                                MDIO_AN_REG_ADV, 0x20);
3142                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3143                                                ext_phy_addr, MDIO_AN_DEVAD,
3144                                                MDIO_AN_REG_CL37_CL73, 0x040c);
3145                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3146                                                ext_phy_addr, MDIO_AN_DEVAD,
3147                                                MDIO_AN_REG_CL37_FC_LD, 0x0020);
3148                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3149                                                ext_phy_addr, MDIO_AN_DEVAD,
3150                                                MDIO_AN_REG_CL37_AN, 0x1000);
3151                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3152                                                ext_phy_addr, MDIO_AN_DEVAD,
3153                                                MDIO_AN_REG_CTRL, 0x1200);
3154
3155                                 /* Enable RX-ALARM control to receive
3156                                 interrupt for 1G speed change */
3157                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3158                                                ext_phy_addr, MDIO_PMA_DEVAD,
3159                                                MDIO_PMA_REG_LASI_CTRL, 0x4);
3160                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3161                                                ext_phy_addr, MDIO_PMA_DEVAD,
3162                                                MDIO_PMA_REG_RX_ALARM_CTRL,
3163                                                0x400);
3164
3165                         } else { /* Default 10G. Set only LASI control */
3166                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3167                                                ext_phy_addr, MDIO_PMA_DEVAD,
3168                                                MDIO_PMA_REG_LASI_CTRL, 1);
3169                         }
3170                         break;
3171                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3172                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
3173                 {
3174                         u16 tmp1;
3175                         u16 rx_alarm_ctrl_val;
3176                         u16 lasi_ctrl_val;
3177                         if (ext_phy_type ==
3178                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
3179                                 rx_alarm_ctrl_val = 0x400;
3180                                 lasi_ctrl_val = 0x0004;
3181                         } else {
3182                                 rx_alarm_ctrl_val = (1<<2);
3183                                 lasi_ctrl_val = 0x0004;
3184                         }
3185
3186                         /* enable LASI */
3187                         bnx2x_cl45_write(bp, params->port,
3188                                    ext_phy_type,
3189                                    ext_phy_addr,
3190                                    MDIO_PMA_DEVAD,
3191                                    MDIO_PMA_REG_RX_ALARM_CTRL,
3192                                    rx_alarm_ctrl_val);
3193
3194                         bnx2x_cl45_write(bp, params->port,
3195                                        ext_phy_type,
3196                                        ext_phy_addr,
3197                                        MDIO_PMA_DEVAD,
3198                                        MDIO_PMA_REG_LASI_CTRL,
3199                                        lasi_ctrl_val);
3200
3201                         bnx2x_8073_set_pause_cl37(params, vars);
3202
3203                         if (ext_phy_type ==
3204                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072){
3205                                 bnx2x_bcm8072_external_rom_boot(params);
3206                         } else {
3207
3208                                 /* In case of 8073 with long xaui lines,
3209                                 don't set the 8073 xaui low power*/
3210                                 bnx2x_bcm8073_set_xaui_low_power_mode(params);
3211                         }
3212
3213                         bnx2x_cl45_read(bp, params->port,
3214                                       ext_phy_type,
3215                                       ext_phy_addr,
3216                                       MDIO_PMA_DEVAD,
3217                                       0xca13,
3218                                       &tmp1);
3219
3220                         bnx2x_cl45_read(bp, params->port,
3221                                       ext_phy_type,
3222                                       ext_phy_addr,
3223                                       MDIO_PMA_DEVAD,
3224                                       MDIO_PMA_REG_RX_ALARM, &tmp1);
3225
3226                         DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1):"
3227                                              "0x%x\n", tmp1);
3228
3229                         /* If this is forced speed, set to KR or KX
3230                          * (all other are not supported)
3231                          */
3232                         if (params->loopback_mode == LOOPBACK_EXT) {
3233                                 bnx2x_bcm807x_force_10G(params);
3234                                 DP(NETIF_MSG_LINK,
3235                                         "Forced speed 10G on 807X\n");
3236                                 break;
3237                         } else {
3238                                 bnx2x_cl45_write(bp, params->port,
3239                                                ext_phy_type, ext_phy_addr,
3240                                                MDIO_PMA_DEVAD,
3241                                                MDIO_PMA_REG_BCM_CTRL,
3242                                                0x0002);
3243                         }
3244                         if (params->req_line_speed != SPEED_AUTO_NEG) {
3245                                 if (params->req_line_speed == SPEED_10000) {
3246                                         val = (1<<7);
3247                                 } else if (params->req_line_speed ==
3248                                            SPEED_2500) {
3249                                         val = (1<<5);
3250                                         /* Note that 2.5G works only
3251                                         when used with 1G advertisment */
3252                                 } else
3253                                         val = (1<<5);
3254                         } else {
3255
3256                                 val = 0;
3257                                 if (params->speed_cap_mask &
3258                                         PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
3259                                         val |= (1<<7);
3260
3261                                 /* Note that 2.5G works only when
3262                                 used with 1G advertisment */
3263                                 if (params->speed_cap_mask &
3264                                         (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
3265                                          PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
3266                                         val |= (1<<5);
3267                                 DP(NETIF_MSG_LINK,
3268                                          "807x autoneg val = 0x%x\n", val);
3269                         }
3270
3271                         bnx2x_cl45_write(bp, params->port,
3272                                        ext_phy_type,
3273                                        ext_phy_addr,
3274                                        MDIO_AN_DEVAD,
3275                                        MDIO_AN_REG_ADV, val);
3276
3277                         if (ext_phy_type ==
3278                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3279
3280                                 bnx2x_cl45_read(bp, params->port,
3281                                               ext_phy_type,
3282                                               ext_phy_addr,
3283                                               MDIO_AN_DEVAD,
3284                                               0x8329, &tmp1);
3285
3286                                 if (((params->speed_cap_mask &
3287                                       PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
3288                                      (params->req_line_speed ==
3289                                       SPEED_AUTO_NEG)) ||
3290                                     (params->req_line_speed ==
3291                                      SPEED_2500)) {
3292                                         u16 phy_ver;
3293                                         /* Allow 2.5G for A1 and above */
3294                                         bnx2x_cl45_read(bp, params->port,
3295                                          PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
3296                                          ext_phy_addr,
3297                                          MDIO_PMA_DEVAD,
3298                                          0xc801, &phy_ver);
3299                                         DP(NETIF_MSG_LINK, "Add 2.5G\n");
3300                                         if (phy_ver > 0)
3301                                                 tmp1 |= 1;
3302                                         else
3303                                                 tmp1 &= 0xfffe;
3304                                 } else {
3305                                         DP(NETIF_MSG_LINK, "Disable 2.5G\n");
3306                                         tmp1 &= 0xfffe;
3307                                 }
3308
3309                                 bnx2x_cl45_write(bp, params->port,
3310                                                ext_phy_type,
3311                                                ext_phy_addr,
3312                                                MDIO_AN_DEVAD,
3313                                                0x8329, tmp1);
3314                         }
3315
3316                         /* Add support for CL37 (passive mode) II */
3317
3318                         bnx2x_cl45_read(bp, params->port,
3319                                        ext_phy_type,
3320                                        ext_phy_addr,
3321                                        MDIO_AN_DEVAD,
3322                                        MDIO_AN_REG_CL37_FC_LD,
3323                                        &tmp1);
3324
3325                         bnx2x_cl45_write(bp, params->port,
3326                                        ext_phy_type,
3327                                        ext_phy_addr,
3328                                        MDIO_AN_DEVAD,
3329                                        MDIO_AN_REG_CL37_FC_LD, (tmp1 |
3330                                        ((params->req_duplex == DUPLEX_FULL) ?
3331                                        0x20 : 0x40)));
3332
3333                         /* Add support for CL37 (passive mode) III */
3334                         bnx2x_cl45_write(bp, params->port,
3335                                        ext_phy_type,
3336                                        ext_phy_addr,
3337                                        MDIO_AN_DEVAD,
3338                                        MDIO_AN_REG_CL37_AN, 0x1000);
3339
3340                         if (ext_phy_type ==
3341                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3342                                 /* The SNR will improve about 2db by changing
3343                                 BW and FEE main tap. Rest commands are executed
3344                                 after link is up*/
3345                                 /*Change FFE main cursor to 5 in EDC register*/
3346                                 if (bnx2x_8073_is_snr_needed(params))
3347                                         bnx2x_cl45_write(bp, params->port,
3348                                                     ext_phy_type,
3349                                                     ext_phy_addr,
3350                                                     MDIO_PMA_DEVAD,
3351                                                     MDIO_PMA_REG_EDC_FFE_MAIN,
3352                                                     0xFB0C);
3353
3354                                 /* Enable FEC (Forware Error Correction)
3355                                 Request in the AN */
3356                                 bnx2x_cl45_read(bp, params->port,
3357                                               ext_phy_type,
3358                                               ext_phy_addr,
3359                                               MDIO_AN_DEVAD,
3360                                               MDIO_AN_REG_ADV2, &tmp1);
3361
3362                                 tmp1 |= (1<<15);
3363
3364                                 bnx2x_cl45_write(bp, params->port,
3365                                                ext_phy_type,
3366                                                ext_phy_addr,
3367                                                MDIO_AN_DEVAD,
3368                                                MDIO_AN_REG_ADV2, tmp1);
3369
3370                         }
3371
3372                         bnx2x_ext_phy_set_pause(params, vars);
3373
3374                         /* Restart autoneg */
3375                         msleep(500);
3376                         bnx2x_cl45_write(bp, params->port,
3377                                        ext_phy_type,
3378                                        ext_phy_addr,
3379                                        MDIO_AN_DEVAD,
3380                                        MDIO_AN_REG_CTRL, 0x1200);
3381                         DP(NETIF_MSG_LINK, "807x Autoneg Restart: "
3382                            "Advertise 1G=%x, 10G=%x\n",
3383                            ((val & (1<<5)) > 0),
3384                            ((val & (1<<7)) > 0));
3385                         break;
3386                 }
3387                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3388                         DP(NETIF_MSG_LINK,
3389                                 "Setting the SFX7101 LASI indication\n");
3390
3391                         bnx2x_cl45_write(bp, params->port,
3392                                        ext_phy_type,
3393                                        ext_phy_addr,
3394                                        MDIO_PMA_DEVAD,
3395                                        MDIO_PMA_REG_LASI_CTRL, 0x1);
3396                         DP(NETIF_MSG_LINK,
3397                           "Setting the SFX7101 LED to blink on traffic\n");
3398                         bnx2x_cl45_write(bp, params->port,
3399                                        ext_phy_type,
3400                                        ext_phy_addr,
3401                                        MDIO_PMA_DEVAD,
3402                                        MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
3403
3404                         bnx2x_ext_phy_set_pause(params, vars);
3405                         /* Restart autoneg */
3406                         bnx2x_cl45_read(bp, params->port,
3407                                       ext_phy_type,
3408                                       ext_phy_addr,
3409                                       MDIO_AN_DEVAD,
3410                                       MDIO_AN_REG_CTRL, &val);
3411                         val |= 0x200;
3412                         bnx2x_cl45_write(bp, params->port,
3413                                        ext_phy_type,
3414                                        ext_phy_addr,
3415                                        MDIO_AN_DEVAD,
3416                                        MDIO_AN_REG_CTRL, val);
3417                         break;
3418                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
3419                         DP(NETIF_MSG_LINK,
3420                                  "XGXS PHY Failure detected 0x%x\n",
3421                                  params->ext_phy_config);
3422                         rc = -EINVAL;
3423                         break;
3424                 default:
3425                         DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
3426                                   params->ext_phy_config);
3427                         rc = -EINVAL;
3428                         break;
3429                 }
3430
3431         } else { /* SerDes */
3432
3433                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3434                 switch (ext_phy_type) {
3435                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
3436                         DP(NETIF_MSG_LINK, "SerDes Direct\n");
3437                         break;
3438
3439                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
3440                         DP(NETIF_MSG_LINK, "SerDes 5482\n");
3441                         break;
3442
3443                 default:
3444                         DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
3445                            params->ext_phy_config);
3446                         break;
3447                 }
3448         }
3449         return rc;
3450 }
3451
3452
3453 static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
3454                                  struct link_vars *vars)
3455 {
3456         struct bnx2x *bp = params->bp;
3457         u32 ext_phy_type;
3458         u8 ext_phy_addr;
3459         u16 val1 = 0, val2;
3460         u16 rx_sd, pcs_status;
3461         u8 ext_phy_link_up = 0;
3462         u8 port = params->port;
3463         if (vars->phy_flags & PHY_XGXS_FLAG) {
3464                 ext_phy_addr = ((params->ext_phy_config &
3465                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3466                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3467
3468                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3469                 switch (ext_phy_type) {
3470                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
3471                         DP(NETIF_MSG_LINK, "XGXS Direct\n");
3472                         ext_phy_link_up = 1;
3473                         break;
3474
3475                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
3476                         DP(NETIF_MSG_LINK, "XGXS 8705\n");
3477                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3478                                       ext_phy_addr,
3479                                       MDIO_WIS_DEVAD,
3480                                       MDIO_WIS_REG_LASI_STATUS, &val1);
3481                         DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
3482
3483                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3484                                       ext_phy_addr,
3485                                       MDIO_WIS_DEVAD,
3486                                       MDIO_WIS_REG_LASI_STATUS, &val1);
3487                         DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
3488
3489                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3490                                       ext_phy_addr,
3491                                       MDIO_PMA_DEVAD,
3492                                       MDIO_PMA_REG_RX_SD, &rx_sd);
3493                         DP(NETIF_MSG_LINK, "8705 rx_sd 0x%x\n", rx_sd);
3494                         ext_phy_link_up = (rx_sd & 0x1);
3495                         if (ext_phy_link_up)
3496                                 vars->line_speed = SPEED_10000;
3497                         break;
3498
3499                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3500                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
3501                         DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
3502                         /* Clear RX Alarm*/
3503                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3504                                       ext_phy_addr,
3505                                       MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM,
3506                                       &val2);
3507                         /* clear LASI indication*/
3508                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3509                                       ext_phy_addr,
3510                                       MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
3511                                       &val1);
3512                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3513                                       ext_phy_addr,
3514                                       MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
3515                                       &val2);
3516                         DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x-->"
3517                                      "0x%x\n", val1, val2);
3518
3519                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3520                                       ext_phy_addr,
3521                                       MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD,
3522                                       &rx_sd);
3523                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3524                                       ext_phy_addr,
3525                                       MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS,
3526                                       &pcs_status);
3527                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3528                                       ext_phy_addr,
3529                                       MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
3530                                       &val2);
3531                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3532                                       ext_phy_addr,
3533                                       MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
3534                                       &val2);
3535
3536                         DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x"
3537                            "  pcs_status 0x%x 1Gbps link_status 0x%x\n",
3538                            rx_sd, pcs_status, val2);
3539                         /* link is up if both bit 0 of pmd_rx_sd and
3540                          * bit 0 of pcs_status are set, or if the autoneg bit
3541                            1 is set
3542                          */
3543                         ext_phy_link_up = ((rx_sd & pcs_status & 0x1) ||
3544                                            (val2 & (1<<1)));
3545                         if (ext_phy_link_up) {
3546                                 if (ext_phy_type ==
3547                                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
3548                                         /* If transmitter is disabled,
3549                                         ignore false link up indication */
3550                                         bnx2x_cl45_read(bp, params->port,
3551                                                    ext_phy_type,
3552                                                    ext_phy_addr,
3553                                                    MDIO_PMA_DEVAD,
3554                                                    MDIO_PMA_REG_PHY_IDENTIFIER,
3555                                                    &val1);
3556                                         if (val1 & (1<<15)) {
3557                                                 DP(NETIF_MSG_LINK, "Tx is "
3558                                                             "disabled\n");
3559                                                 ext_phy_link_up = 0;
3560                                                 break;
3561                                         }
3562                                 }
3563
3564                                 if (val2 & (1<<1))
3565                                         vars->line_speed = SPEED_1000;
3566                                 else
3567                                         vars->line_speed = SPEED_10000;
3568                         }
3569
3570                         break;
3571                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3572                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
3573                 {
3574                         u16 link_status = 0;
3575                         u16 an1000_status = 0;
3576                         if (ext_phy_type ==
3577                              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
3578                                 bnx2x_cl45_read(bp, params->port,
3579                                       ext_phy_type,
3580                                       ext_phy_addr,
3581                                       MDIO_PCS_DEVAD,
3582                                       MDIO_PCS_REG_LASI_STATUS, &val1);
3583                         bnx2x_cl45_read(bp, params->port,
3584                                       ext_phy_type,
3585                                       ext_phy_addr,
3586                                       MDIO_PCS_DEVAD,
3587                                       MDIO_PCS_REG_LASI_STATUS, &val2);
3588                         DP(NETIF_MSG_LINK,
3589                                  "870x LASI status 0x%x->0x%x\n",
3590                                   val1, val2);
3591
3592                         } else {
3593                                 /* In 8073, port1 is directed through emac0 and
3594                                  * port0 is directed through emac1
3595                                  */
3596                                 bnx2x_cl45_read(bp, params->port,
3597                                               ext_phy_type,
3598                                               ext_phy_addr,
3599                                               MDIO_PMA_DEVAD,
3600                                               MDIO_PMA_REG_LASI_STATUS, &val1);
3601
3602                                 DP(NETIF_MSG_LINK,
3603                                          "8703 LASI status 0x%x\n",
3604                                           val1);
3605                         }
3606
3607                         /* clear the interrupt LASI status register */
3608                         bnx2x_cl45_read(bp, params->port,
3609                                       ext_phy_type,
3610                                       ext_phy_addr,
3611                                       MDIO_PCS_DEVAD,
3612                                       MDIO_PCS_REG_STATUS, &val2);
3613                         bnx2x_cl45_read(bp, params->port,
3614                                       ext_phy_type,
3615                                       ext_phy_addr,
3616                                       MDIO_PCS_DEVAD,
3617                                       MDIO_PCS_REG_STATUS, &val1);
3618                         DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n",
3619                            val2, val1);
3620                         /* Clear MSG-OUT */
3621                         bnx2x_cl45_read(bp, params->port,
3622                                       ext_phy_type,
3623                                       ext_phy_addr,
3624                                       MDIO_PMA_DEVAD,
3625                                       0xca13,
3626                                       &val1);
3627
3628                         /* Check the LASI */
3629                         bnx2x_cl45_read(bp, params->port,
3630                                       ext_phy_type,
3631                                       ext_phy_addr,
3632                                       MDIO_PMA_DEVAD,
3633                                       MDIO_PMA_REG_RX_ALARM, &val2);
3634
3635                         DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
3636
3637                         /* Check the link status */
3638                         bnx2x_cl45_read(bp, params->port,
3639                                       ext_phy_type,
3640                                       ext_phy_addr,
3641                                       MDIO_PCS_DEVAD,
3642                                       MDIO_PCS_REG_STATUS, &val2);
3643                         DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
3644
3645                         bnx2x_cl45_read(bp, params->port,
3646                                       ext_phy_type,
3647                                       ext_phy_addr,
3648                                       MDIO_PMA_DEVAD,
3649                                       MDIO_PMA_REG_STATUS, &val2);
3650                         bnx2x_cl45_read(bp, params->port,
3651                                       ext_phy_type,
3652                                       ext_phy_addr,
3653                                       MDIO_PMA_DEVAD,
3654                                       MDIO_PMA_REG_STATUS, &val1);
3655                         ext_phy_link_up = ((val1 & 4) == 4);
3656                         DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
3657                         if (ext_phy_type ==
3658                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3659
3660                                 if (ext_phy_link_up &&
3661                                     ((params->req_line_speed !=
3662                                         SPEED_10000))) {
3663                                         if (bnx2x_bcm8073_xaui_wa(params)
3664                                              != 0) {
3665                                                 ext_phy_link_up = 0;
3666                                                 break;
3667                                         }
3668                                 }
3669                                 bnx2x_cl45_read(bp, params->port,
3670                                                       ext_phy_type,
3671                                                       ext_phy_addr,
3672                                                       MDIO_AN_DEVAD,
3673                                                       0x8304,
3674                                                       &an1000_status);
3675                                 bnx2x_cl45_read(bp, params->port,
3676                                                       ext_phy_type,
3677                                                       ext_phy_addr,
3678                                                       MDIO_AN_DEVAD,
3679                                                       0x8304,
3680                                                       &an1000_status);
3681
3682                                 /* Check the link status on 1.1.2 */
3683                                 bnx2x_cl45_read(bp, params->port,
3684                                               ext_phy_type,
3685                                               ext_phy_addr,
3686                                               MDIO_PMA_DEVAD,
3687                                               MDIO_PMA_REG_STATUS, &val2);
3688                                 bnx2x_cl45_read(bp, params->port,
3689                                               ext_phy_type,
3690                                               ext_phy_addr,
3691                                               MDIO_PMA_DEVAD,
3692                                               MDIO_PMA_REG_STATUS, &val1);
3693                                 DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
3694                                              "an_link_status=0x%x\n",
3695                                           val2, val1, an1000_status);
3696
3697                                         ext_phy_link_up = (((val1 & 4) == 4) ||
3698                                                 (an1000_status & (1<<1)));
3699                                 if (ext_phy_link_up &&
3700                                     bnx2x_8073_is_snr_needed(params)) {
3701                                         /* The SNR will improve about 2dbby
3702                                         changing the BW and FEE main tap.*/
3703
3704                                         /* The 1st write to change FFE main
3705                                         tap is set before restart AN */
3706                                         /* Change PLL Bandwidth in EDC
3707                                         register */
3708                                         bnx2x_cl45_write(bp, port, ext_phy_type,
3709                                                     ext_phy_addr,
3710                                                     MDIO_PMA_DEVAD,
3711                                                     MDIO_PMA_REG_PLL_BANDWIDTH,
3712                                                     0x26BC);
3713
3714                                         /* Change CDR Bandwidth in EDC
3715                                         register */
3716                                         bnx2x_cl45_write(bp, port, ext_phy_type,
3717                                                     ext_phy_addr,
3718                                                     MDIO_PMA_DEVAD,
3719                                                     MDIO_PMA_REG_CDR_BANDWIDTH,
3720                                                     0x0333);
3721
3722
3723                                 }
3724                                 bnx2x_cl45_read(bp, params->port,
3725                                                       ext_phy_type,
3726                                                       ext_phy_addr,
3727                                                       MDIO_PMA_DEVAD,
3728                                                       0xc820,
3729                                                       &link_status);
3730
3731                                 /* Bits 0..2 --> speed detected,
3732                                    bits 13..15--> link is down */
3733                                 if ((link_status & (1<<2)) &&
3734                                     (!(link_status & (1<<15)))) {
3735                                         ext_phy_link_up = 1;
3736                                         vars->line_speed = SPEED_10000;
3737                                         DP(NETIF_MSG_LINK,
3738                                                  "port %x: External link"
3739                                                  " up in 10G\n", params->port);
3740                                 } else if ((link_status & (1<<1)) &&
3741                                            (!(link_status & (1<<14)))) {
3742                                         ext_phy_link_up = 1;
3743                                         vars->line_speed = SPEED_2500;
3744                                         DP(NETIF_MSG_LINK,
3745                                                  "port %x: External link"
3746                                                  " up in 2.5G\n", params->port);
3747                                 } else if ((link_status & (1<<0)) &&
3748                                            (!(link_status & (1<<13)))) {
3749                                         ext_phy_link_up = 1;
3750                                         vars->line_speed = SPEED_1000;
3751                                         DP(NETIF_MSG_LINK,
3752                                                  "port %x: External link"
3753                                                  " up in 1G\n", params->port);
3754                                 } else {
3755                                         ext_phy_link_up = 0;
3756                                         DP(NETIF_MSG_LINK,
3757                                                  "port %x: External link"
3758                                                  " is down\n", params->port);
3759                                 }
3760                         } else {
3761                                 /* See if 1G link is up for the 8072 */
3762                                 bnx2x_cl45_read(bp, params->port,
3763                                                       ext_phy_type,
3764                                                       ext_phy_addr,
3765                                                       MDIO_AN_DEVAD,
3766                                                       0x8304,
3767                                                       &an1000_status);
3768                                 bnx2x_cl45_read(bp, params->port,
3769                                                       ext_phy_type,
3770                                                       ext_phy_addr,
3771                                                       MDIO_AN_DEVAD,
3772                                                       0x8304,
3773                                                       &an1000_status);
3774                                 if (an1000_status & (1<<1)) {
3775                                         ext_phy_link_up = 1;
3776                                         vars->line_speed = SPEED_1000;
3777                                         DP(NETIF_MSG_LINK,
3778                                                  "port %x: External link"
3779                                                  " up in 1G\n", params->port);
3780                                 } else if (ext_phy_link_up) {
3781                                         ext_phy_link_up = 1;
3782                                         vars->line_speed = SPEED_10000;
3783                                         DP(NETIF_MSG_LINK,
3784                                                  "port %x: External link"
3785                                                  " up in 10G\n", params->port);
3786                                 }
3787                         }
3788
3789
3790                         break;
3791                 }
3792                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3793                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3794                                       ext_phy_addr,
3795                                       MDIO_PMA_DEVAD,
3796                                       MDIO_PMA_REG_LASI_STATUS, &val2);
3797                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3798                                       ext_phy_addr,
3799                                       MDIO_PMA_DEVAD,
3800                                       MDIO_PMA_REG_LASI_STATUS, &val1);
3801                         DP(NETIF_MSG_LINK,
3802                                  "10G-base-T LASI status 0x%x->0x%x\n",
3803                                   val2, val1);
3804                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3805                                       ext_phy_addr,
3806                                       MDIO_PMA_DEVAD,
3807                                       MDIO_PMA_REG_STATUS, &val2);
3808                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3809                                       ext_phy_addr,
3810                                       MDIO_PMA_DEVAD,
3811                                       MDIO_PMA_REG_STATUS, &val1);
3812                         DP(NETIF_MSG_LINK,
3813                                  "10G-base-T PMA status 0x%x->0x%x\n",
3814                                  val2, val1);
3815                         ext_phy_link_up = ((val1 & 4) == 4);
3816                         /* if link is up
3817                          * print the AN outcome of the SFX7101 PHY
3818                          */
3819                         if (ext_phy_link_up) {
3820                                 bnx2x_cl45_read(bp, params->port,
3821                                               ext_phy_type,
3822                                               ext_phy_addr,
3823                                               MDIO_AN_DEVAD,
3824                                               MDIO_AN_REG_MASTER_STATUS,
3825                                               &val2);
3826                                 vars->line_speed = SPEED_10000;
3827                                 DP(NETIF_MSG_LINK,
3828                                          "SFX7101 AN status 0x%x->Master=%x\n",
3829                                           val2,
3830                                          (val2 & (1<<14)));
3831                         }
3832                         break;
3833
3834                 default:
3835                         DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
3836                            params->ext_phy_config);
3837                         ext_phy_link_up = 0;
3838                         break;
3839                 }
3840
3841         } else { /* SerDes */
3842                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3843                 switch (ext_phy_type) {
3844                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
3845                         DP(NETIF_MSG_LINK, "SerDes Direct\n");
3846                         ext_phy_link_up = 1;
3847                         break;
3848
3849                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
3850                         DP(NETIF_MSG_LINK, "SerDes 5482\n");
3851                         ext_phy_link_up = 1;
3852                         break;
3853
3854                 default:
3855                         DP(NETIF_MSG_LINK,
3856                                  "BAD SerDes ext_phy_config 0x%x\n",
3857                                  params->ext_phy_config);
3858                         ext_phy_link_up = 0;
3859                         break;
3860                 }
3861         }
3862
3863         return ext_phy_link_up;
3864 }
3865
3866 static void bnx2x_link_int_enable(struct link_params *params)
3867 {
3868         u8 port = params->port;
3869         u32 ext_phy_type;
3870         u32 mask;
3871         struct bnx2x *bp = params->bp;
3872         /* setting the status to report on link up
3873            for either XGXS or SerDes */
3874
3875         if (params->switch_cfg == SWITCH_CFG_10G) {
3876                 mask = (NIG_MASK_XGXS0_LINK10G |
3877                         NIG_MASK_XGXS0_LINK_STATUS);
3878                 DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
3879                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3880                 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
3881                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
3882                     (ext_phy_type !=
3883                                 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) {
3884                         mask |= NIG_MASK_MI_INT;
3885                         DP(NETIF_MSG_LINK, "enabled external phy int\n");
3886                 }
3887
3888         } else { /* SerDes */
3889                 mask = NIG_MASK_SERDES0_LINK_STATUS;
3890                 DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
3891                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3892                 if ((ext_phy_type !=
3893                                 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
3894                     (ext_phy_type !=
3895                                 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) {
3896                         mask |= NIG_MASK_MI_INT;
3897                         DP(NETIF_MSG_LINK, "enabled external phy int\n");
3898                 }
3899         }
3900         bnx2x_bits_en(bp,
3901                       NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
3902                       mask);
3903         DP(NETIF_MSG_LINK, "port %x, is_xgxs=%x, int_status 0x%x\n", port,
3904                  (params->switch_cfg == SWITCH_CFG_10G),
3905                  REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
3906
3907         DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
3908                  REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
3909                  REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
3910                  REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
3911         DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
3912            REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
3913            REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
3914 }
3915
3916
3917 /*
3918  * link management
3919  */
3920 static void bnx2x_link_int_ack(struct link_params *params,
3921                              struct link_vars *vars, u8 is_10g)
3922 {
3923         struct bnx2x *bp = params->bp;
3924         u8 port = params->port;
3925
3926         /* first reset all status
3927          * we assume only one line will be change at a time */
3928         bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3929                      (NIG_STATUS_XGXS0_LINK10G |
3930                       NIG_STATUS_XGXS0_LINK_STATUS |
3931                       NIG_STATUS_SERDES0_LINK_STATUS));
3932         if (vars->phy_link_up) {
3933                 if (is_10g) {
3934                         /* Disable the 10G link interrupt
3935                          * by writing 1 to the status register
3936                          */
3937                         DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
3938                         bnx2x_bits_en(bp,
3939                                       NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3940                                       NIG_STATUS_XGXS0_LINK10G);
3941
3942                 } else if (params->switch_cfg == SWITCH_CFG_10G) {
3943                         /* Disable the link interrupt
3944                          * by writing 1 to the relevant lane
3945                          * in the status register
3946                          */
3947                         u32 ser_lane = ((params->lane_config &
3948                                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
3949                                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
3950
3951                         DP(NETIF_MSG_LINK, "1G XGXS phy link up\n");
3952                         bnx2x_bits_en(bp,
3953                                       NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3954                                       ((1 << ser_lane) <<
3955                                        NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
3956
3957                 } else { /* SerDes */
3958                         DP(NETIF_MSG_LINK, "SerDes phy link up\n");
3959                         /* Disable the link interrupt
3960                          * by writing 1 to the status register
3961                          */
3962                         bnx2x_bits_en(bp,
3963                                       NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3964                                       NIG_STATUS_SERDES0_LINK_STATUS);
3965                 }
3966
3967         } else { /* link_down */
3968         }
3969 }
3970
3971 static u8 bnx2x_format_ver(u32 num, u8 *str, u16 len)
3972 {
3973         u8 *str_ptr = str;
3974         u32 mask = 0xf0000000;
3975         u8 shift = 8*4;
3976         u8 digit;
3977         if (len < 10) {
3978                 /* Need more than 10chars for this format */
3979                 *str_ptr = '\0';
3980                 return -EINVAL;
3981         }
3982         while (shift > 0) {
3983
3984                 shift -= 4;
3985                 digit = ((num & mask) >> shift);
3986                 if (digit < 0xa)
3987                         *str_ptr = digit + '0';
3988                 else
3989                         *str_ptr = digit - 0xa + 'a';
3990                 str_ptr++;
3991                 mask = mask >> 4;
3992                 if (shift == 4*4) {
3993                         *str_ptr = ':';
3994                         str_ptr++;
3995                 }
3996         }
3997         *str_ptr = '\0';
3998         return 0;
3999 }
4000
4001
4002 static void bnx2x_turn_on_ef(struct bnx2x *bp, u8 port, u8 ext_phy_addr,
4003                            u32 ext_phy_type)
4004 {
4005         u32 cnt = 0;
4006         u16 ctrl = 0;
4007         /* Enable EMAC0 in to enable MDIO */
4008         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
4009                (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
4010         msleep(5);
4011
4012         /* take ext phy out of reset */
4013         bnx2x_set_gpio(bp,
4014                           MISC_REGISTERS_GPIO_2,
4015                           MISC_REGISTERS_GPIO_HIGH,
4016                           port);
4017
4018         bnx2x_set_gpio(bp,
4019                           MISC_REGISTERS_GPIO_1,
4020                           MISC_REGISTERS_GPIO_HIGH,
4021                           port);
4022
4023         /* wait for 5ms */
4024         msleep(5);
4025
4026         for (cnt = 0; cnt < 1000; cnt++) {
4027                 msleep(1);
4028                 bnx2x_cl45_read(bp, port,
4029                               ext_phy_type,
4030                               ext_phy_addr,
4031                               MDIO_PMA_DEVAD,
4032                               MDIO_PMA_REG_CTRL,
4033                                &ctrl);
4034                 if (!(ctrl & (1<<15))) {
4035                         DP(NETIF_MSG_LINK, "Reset completed\n\n");
4036                                 break;
4037                 }
4038         }
4039 }
4040
4041 static void bnx2x_turn_off_sf(struct bnx2x *bp, u8 port)
4042 {
4043         /* put sf to reset */
4044         bnx2x_set_gpio(bp,
4045                           MISC_REGISTERS_GPIO_1,
4046                           MISC_REGISTERS_GPIO_LOW,
4047                           port);
4048         bnx2x_set_gpio(bp,
4049                           MISC_REGISTERS_GPIO_2,
4050                           MISC_REGISTERS_GPIO_LOW,
4051                           port);
4052 }
4053
4054 u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
4055                               u8 *version, u16 len)
4056 {
4057         struct bnx2x *bp = params->bp;
4058         u32 ext_phy_type = 0;
4059         u16 val = 0;
4060         u8 ext_phy_addr = 0 ;
4061         u8 status = 0 ;
4062         u32 ver_num;
4063
4064         if (version == NULL || params == NULL)
4065                 return -EINVAL;
4066
4067         /* reset the returned value to zero */
4068         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4069         ext_phy_addr = ((params->ext_phy_config &
4070                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4071                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4072
4073         switch (ext_phy_type) {
4074         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4075
4076                 if (len < 5)
4077                         return -EINVAL;
4078
4079                 /* Take ext phy out of reset */
4080                 if (!driver_loaded)
4081                         bnx2x_turn_on_ef(bp, params->port, ext_phy_addr,
4082                                        ext_phy_type);
4083
4084                 /*  wait for 1ms */
4085                 msleep(1);
4086
4087                 bnx2x_cl45_read(bp, params->port,
4088                               ext_phy_type,
4089                               ext_phy_addr,
4090                               MDIO_PMA_DEVAD,
4091                               MDIO_PMA_REG_7101_VER1, &val);
4092                 version[2] = (val & 0xFF);
4093                 version[3] = ((val & 0xFF00)>>8);
4094
4095                 bnx2x_cl45_read(bp, params->port,
4096                               ext_phy_type,
4097                               ext_phy_addr,
4098                               MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2,
4099                               &val);
4100                 version[0] = (val & 0xFF);
4101                 version[1] = ((val & 0xFF00)>>8);
4102                 version[4] = '\0';
4103
4104                 if (!driver_loaded)
4105                         bnx2x_turn_off_sf(bp, params->port);
4106                 break;
4107         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4108         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4109         {
4110                 /* Take ext phy out of reset */
4111                 if (!driver_loaded)
4112                         bnx2x_turn_on_ef(bp, params->port, ext_phy_addr,
4113                                        ext_phy_type);
4114
4115                 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4116                               ext_phy_addr,
4117                               MDIO_PMA_DEVAD,
4118                               MDIO_PMA_REG_ROM_VER1, &val);
4119                 ver_num = val<<16;
4120                 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4121                               ext_phy_addr,
4122                               MDIO_PMA_DEVAD,
4123                               MDIO_PMA_REG_ROM_VER2, &val);
4124                 ver_num |= val;
4125                 status = bnx2x_format_ver(ver_num, version, len);
4126                 break;
4127         }
4128         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
4129         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
4130         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
4131                 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4132                               ext_phy_addr,
4133                               MDIO_PMA_DEVAD,
4134                               MDIO_PMA_REG_ROM_VER1, &val);
4135                 ver_num = val<<16;
4136                 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4137                               ext_phy_addr,
4138                               MDIO_PMA_DEVAD,
4139                               MDIO_PMA_REG_ROM_VER2, &val);
4140                 ver_num |= val;
4141                 status = bnx2x_format_ver(ver_num, version, len);
4142                 break;
4143
4144         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4145                 break;
4146
4147         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
4148                 DP(NETIF_MSG_LINK, "bnx2x_get_ext_phy_fw_version:"
4149                                     " type is FAILURE!\n");
4150                 status = -EINVAL;
4151                 break;
4152
4153         default:
4154                 break;
4155         }
4156         return status;
4157 }
4158
4159 static void bnx2x_set_xgxs_loopback(struct link_params *params,
4160                                   struct link_vars *vars,
4161                                   u8 is_10g)
4162 {
4163         u8 port = params->port;
4164         struct bnx2x *bp = params->bp;
4165
4166         if (is_10g) {
4167                 u32 md_devad;
4168
4169                 DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
4170
4171                 /* change the uni_phy_addr in the nig */
4172                 md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
4173                                           port*0x18));
4174
4175                 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
4176
4177                 bnx2x_cl45_write(bp, port, 0,
4178                                params->phy_addr,
4179                                5,
4180                                (MDIO_REG_BANK_AER_BLOCK +
4181                                 (MDIO_AER_BLOCK_AER_REG & 0xf)),
4182                                0x2800);
4183
4184                 bnx2x_cl45_write(bp, port, 0,
4185                                params->phy_addr,
4186                                5,
4187                                (MDIO_REG_BANK_CL73_IEEEB0 +
4188                                 (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
4189                                0x6041);
4190                 msleep(200);
4191                 /* set aer mmd back */
4192                 bnx2x_set_aer_mmd(params, vars);
4193
4194                 /* and md_devad */
4195                 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
4196                             md_devad);
4197
4198         } else {
4199                 u16 mii_control;
4200
4201                 DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
4202
4203                 CL45_RD_OVER_CL22(bp, port,
4204                                       params->phy_addr,
4205                                       MDIO_REG_BANK_COMBO_IEEE0,
4206                                       MDIO_COMBO_IEEE0_MII_CONTROL,
4207                                       &mii_control);
4208
4209                 CL45_WR_OVER_CL22(bp, port,
4210                                       params->phy_addr,
4211                                       MDIO_REG_BANK_COMBO_IEEE0,
4212                                       MDIO_COMBO_IEEE0_MII_CONTROL,
4213                                       (mii_control |
4214                                        MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK));
4215         }
4216 }
4217
4218
4219 static void bnx2x_ext_phy_loopback(struct link_params *params)
4220 {
4221         struct bnx2x *bp = params->bp;
4222         u8 ext_phy_addr;
4223         u32 ext_phy_type;
4224
4225         if (params->switch_cfg == SWITCH_CFG_10G) {
4226                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4227                 /* CL37 Autoneg Enabled */
4228                 ext_phy_addr = ((params->ext_phy_config &
4229                                         PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4230                                         PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4231                 switch (ext_phy_type) {
4232                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4233                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
4234                         DP(NETIF_MSG_LINK,
4235                                 "ext_phy_loopback: We should not get here\n");
4236                         break;
4237                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
4238                         DP(NETIF_MSG_LINK, "ext_phy_loopback: 8705\n");
4239                         break;
4240                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
4241                         DP(NETIF_MSG_LINK, "ext_phy_loopback: 8706\n");
4242                         break;
4243                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
4244                         DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
4245                         bnx2x_cl45_write(bp, params->port, ext_phy_type,
4246                                        ext_phy_addr,
4247                                        MDIO_PMA_DEVAD,
4248                                        MDIO_PMA_REG_CTRL,
4249                                        0x0001);
4250                         break;
4251                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4252                         /* SFX7101_XGXS_TEST1 */
4253                         bnx2x_cl45_write(bp, params->port, ext_phy_type,
4254                                        ext_phy_addr,
4255                                        MDIO_XS_DEVAD,
4256                                        MDIO_XS_SFX7101_XGXS_TEST1,
4257                                        0x100);
4258                         DP(NETIF_MSG_LINK,
4259                                 "ext_phy_loopback: set ext phy loopback\n");
4260                         break;
4261                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4262
4263                         break;
4264                 } /* switch external PHY type */
4265         } else {
4266                 /* serdes */
4267                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
4268                 ext_phy_addr = (params->ext_phy_config  &
4269                 PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK)
4270                 >> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT;
4271         }
4272 }
4273
4274
4275 /*
4276  *------------------------------------------------------------------------
4277  * bnx2x_override_led_value -
4278  *
4279  * Override the led value of the requsted led
4280  *
4281  *------------------------------------------------------------------------
4282  */
4283 u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port,
4284                           u32 led_idx, u32 value)
4285 {
4286         u32 reg_val;
4287
4288         /* If port 0 then use EMAC0, else use EMAC1*/
4289         u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
4290
4291         DP(NETIF_MSG_LINK,
4292                  "bnx2x_override_led_value() port %x led_idx %d value %d\n",
4293                  port, led_idx, value);
4294
4295         switch (led_idx) {
4296         case 0: /* 10MB led */
4297                 /* Read the current value of the LED register in
4298                 the EMAC block */
4299                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4300                 /* Set the OVERRIDE bit to 1 */
4301                 reg_val |= EMAC_LED_OVERRIDE;
4302                 /* If value is 1, set the 10M_OVERRIDE bit,
4303                 otherwise reset it.*/
4304                 reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) :
4305                         (reg_val & ~EMAC_LED_10MB_OVERRIDE);
4306                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4307                 break;
4308         case 1: /*100MB led    */
4309                 /*Read the current value of the LED register in
4310                 the EMAC block */
4311                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4312                 /*  Set the OVERRIDE bit to 1 */
4313                 reg_val |= EMAC_LED_OVERRIDE;
4314                 /*  If value is 1, set the 100M_OVERRIDE bit,
4315                 otherwise reset it.*/
4316                 reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) :
4317                         (reg_val & ~EMAC_LED_100MB_OVERRIDE);
4318                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4319                 break;
4320         case 2: /* 1000MB led */
4321                 /* Read the current value of the LED register in the
4322                 EMAC block */
4323                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4324                 /* Set the OVERRIDE bit to 1 */
4325                 reg_val |= EMAC_LED_OVERRIDE;
4326                 /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
4327                 reset it. */
4328                 reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) :
4329                         (reg_val & ~EMAC_LED_1000MB_OVERRIDE);
4330                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4331                 break;
4332         case 3: /* 2500MB led */
4333                 /*  Read the current value of the LED register in the
4334                 EMAC block*/
4335                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4336                 /* Set the OVERRIDE bit to 1 */
4337                 reg_val |= EMAC_LED_OVERRIDE;
4338                 /*  If value is 1, set the 2500M_OVERRIDE bit, otherwise
4339                 reset it.*/
4340                 reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) :
4341                         (reg_val & ~EMAC_LED_2500MB_OVERRIDE);
4342                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4343                 break;
4344         case 4: /*10G led */
4345                 if (port == 0) {
4346                         REG_WR(bp, NIG_REG_LED_10G_P0,
4347                                     value);
4348                 } else {
4349                         REG_WR(bp, NIG_REG_LED_10G_P1,
4350                                     value);
4351                 }
4352                 break;
4353         case 5: /* TRAFFIC led */
4354                 /* Find if the traffic control is via BMAC or EMAC */
4355                 if (port == 0)
4356                         reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN);
4357                 else
4358                         reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN);
4359
4360                 /*  Override the traffic led in the EMAC:*/
4361                 if (reg_val == 1) {
4362                         /* Read the current value of the LED register in
4363                         the EMAC block */
4364                         reg_val = REG_RD(bp, emac_base +
4365                                              EMAC_REG_EMAC_LED);
4366                         /* Set the TRAFFIC_OVERRIDE bit to 1 */
4367                         reg_val |= EMAC_LED_OVERRIDE;
4368                         /* If value is 1, set the TRAFFIC bit, otherwise
4369                         reset it.*/
4370                         reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) :
4371                                 (reg_val & ~EMAC_LED_TRAFFIC);
4372                         REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4373                 } else { /* Override the traffic led in the BMAC: */
4374                         REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
4375                                    + port*4, 1);
4376                         REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4,
4377                                     value);
4378                 }
4379                 break;
4380         default:
4381                 DP(NETIF_MSG_LINK,
4382                          "bnx2x_override_led_value() unknown led index %d "
4383                          "(should be 0-5)\n", led_idx);
4384                 return -EINVAL;
4385         }
4386
4387         return 0;
4388 }
4389
4390
4391 u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed,
4392                u16 hw_led_mode, u32 chip_id)
4393 {
4394         u8 rc = 0;
4395         u32 tmp;
4396         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
4397         DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
4398         DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
4399                  speed, hw_led_mode);
4400         switch (mode) {
4401         case LED_MODE_OFF:
4402                 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
4403                 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
4404                            SHARED_HW_CFG_LED_MAC1);
4405
4406                 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
4407                 EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
4408                 break;
4409
4410         case LED_MODE_OPER:
4411                 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode);
4412                 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 +
4413                            port*4, 0);
4414                 /* Set blinking rate to ~15.9Hz */
4415                 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
4416                            LED_BLINK_RATE_VAL);
4417                 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
4418                            port*4, 1);
4419                 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
4420                 EMAC_WR(bp, EMAC_REG_EMAC_LED,
4421                             (tmp & (~EMAC_LED_OVERRIDE)));
4422
4423                 if (!CHIP_IS_E1H(bp) &&
4424                     ((speed == SPEED_2500) ||
4425                      (speed == SPEED_1000) ||
4426                      (speed == SPEED_100) ||
4427                      (speed == SPEED_10))) {
4428                         /* On Everest 1 Ax chip versions for speeds less than
4429                         10G LED scheme is different */
4430                         REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
4431                                    + port*4, 1);
4432                         REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
4433                                    port*4, 0);
4434                         REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
4435                                    port*4, 1);
4436                 }
4437                 break;
4438
4439         default:
4440                 rc = -EINVAL;
4441                 DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
4442                          mode);
4443                 break;
4444         }
4445         return rc;
4446
4447 }
4448
4449 u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars)
4450 {
4451         struct bnx2x *bp = params->bp;
4452         u16 gp_status = 0;
4453
4454         CL45_RD_OVER_CL22(bp, params->port,
4455                               params->phy_addr,
4456                               MDIO_REG_BANK_GP_STATUS,
4457                               MDIO_GP_STATUS_TOP_AN_STATUS1,
4458                               &gp_status);
4459         /* link is up only if both local phy and external phy are up */
4460         if ((gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) &&
4461             bnx2x_ext_phy_is_link_up(params, vars))
4462                 return 0;
4463
4464         return -ESRCH;
4465 }
4466
4467 static u8 bnx2x_link_initialize(struct link_params *params,
4468                               struct link_vars *vars)
4469 {
4470         struct bnx2x *bp = params->bp;
4471         u8 port = params->port;
4472         u8 rc = 0;
4473         u8 non_ext_phy;
4474         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4475         /* Activate the external PHY */
4476         bnx2x_ext_phy_reset(params, vars);
4477
4478         bnx2x_set_aer_mmd(params, vars);
4479
4480         if (vars->phy_flags & PHY_XGXS_FLAG)
4481                 bnx2x_set_master_ln(params);
4482
4483         rc = bnx2x_reset_unicore(params);
4484         /* reset the SerDes and wait for reset bit return low */
4485         if (rc != 0)
4486                 return rc;
4487
4488         bnx2x_set_aer_mmd(params, vars);
4489
4490         /* setting the masterLn_def again after the reset */
4491         if (vars->phy_flags & PHY_XGXS_FLAG) {
4492                 bnx2x_set_master_ln(params);
4493                 bnx2x_set_swap_lanes(params);
4494         }
4495
4496         if (vars->phy_flags & PHY_XGXS_FLAG) {
4497                 if ((params->req_line_speed &&
4498                     ((params->req_line_speed == SPEED_100) ||
4499                      (params->req_line_speed == SPEED_10))) ||
4500                     (!params->req_line_speed &&
4501                      (params->speed_cap_mask >=
4502                        PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
4503                      (params->speed_cap_mask <
4504                        PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
4505                      ))  {
4506                         vars->phy_flags |= PHY_SGMII_FLAG;
4507                 } else {
4508                         vars->phy_flags &= ~PHY_SGMII_FLAG;
4509                 }
4510         }
4511         /* In case of external phy existance, the line speed would be the
4512          line speed linked up by the external phy. In case it is direct only,
4513           then the line_speed during initialization will be equal to the
4514            req_line_speed*/
4515         vars->line_speed = params->req_line_speed;
4516
4517         bnx2x_calc_ieee_aneg_adv(params, &vars->ieee_fc);
4518
4519         /* init ext phy and enable link state int */
4520         non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
4521                        (params->loopback_mode == LOOPBACK_XGXS_10) ||
4522                        (params->loopback_mode == LOOPBACK_EXT_PHY));
4523
4524         if (non_ext_phy ||
4525             (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
4526             (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726)) {
4527                 if (params->req_line_speed == SPEED_AUTO_NEG)
4528                         bnx2x_set_parallel_detection(params, vars->phy_flags);
4529                 bnx2x_init_internal_phy(params, vars);
4530         }
4531
4532         if (!non_ext_phy)
4533                 rc |= bnx2x_ext_phy_init(params, vars);
4534
4535         bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4536                      (NIG_STATUS_XGXS0_LINK10G |
4537                       NIG_STATUS_XGXS0_LINK_STATUS |
4538                       NIG_STATUS_SERDES0_LINK_STATUS));
4539
4540         return rc;
4541
4542 }
4543
4544
4545 u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
4546 {
4547         struct bnx2x *bp = params->bp;
4548
4549         u32 val;
4550         DP(NETIF_MSG_LINK, "Phy Initialization started \n");
4551         DP(NETIF_MSG_LINK, "req_speed = %d, req_flowctrl=%d\n",
4552                   params->req_line_speed, params->req_flow_ctrl);
4553         vars->link_status = 0;
4554         vars->phy_link_up = 0;
4555         vars->link_up = 0;
4556         vars->line_speed = 0;
4557         vars->duplex = DUPLEX_FULL;
4558         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4559         vars->mac_type = MAC_TYPE_NONE;
4560
4561         if (params->switch_cfg ==  SWITCH_CFG_1G)
4562                 vars->phy_flags = PHY_SERDES_FLAG;
4563         else
4564                 vars->phy_flags = PHY_XGXS_FLAG;
4565
4566
4567         /* disable attentions */
4568         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
4569                        (NIG_MASK_XGXS0_LINK_STATUS |
4570                         NIG_MASK_XGXS0_LINK10G |
4571                         NIG_MASK_SERDES0_LINK_STATUS |
4572                         NIG_MASK_MI_INT));
4573
4574         bnx2x_emac_init(params, vars);
4575
4576         if (CHIP_REV_IS_FPGA(bp)) {
4577                 vars->link_up = 1;
4578                 vars->line_speed = SPEED_10000;
4579                 vars->duplex = DUPLEX_FULL;
4580                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4581                 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
4582                 /* enable on E1.5 FPGA */
4583                 if (CHIP_IS_E1H(bp)) {
4584                         vars->flow_ctrl |=
4585                                 (BNX2X_FLOW_CTRL_TX | BNX2X_FLOW_CTRL_RX);
4586                         vars->link_status |=
4587                                         (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
4588                                          LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
4589                 }
4590
4591                 bnx2x_emac_enable(params, vars, 0);
4592                 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
4593                 /* disable drain */
4594                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
4595                                     + params->port*4, 0);
4596
4597                 /* update shared memory */
4598                 bnx2x_update_mng(params, vars->link_status);
4599
4600                 return 0;
4601
4602         } else
4603         if (CHIP_REV_IS_EMUL(bp)) {
4604
4605                 vars->link_up = 1;
4606                 vars->line_speed = SPEED_10000;
4607                 vars->duplex = DUPLEX_FULL;
4608                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4609                 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
4610
4611                 bnx2x_bmac_enable(params, vars, 0);
4612
4613                 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
4614                 /* Disable drain */
4615                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
4616                                     + params->port*4, 0);
4617
4618                 /* update shared memory */
4619                 bnx2x_update_mng(params, vars->link_status);
4620
4621                 return 0;
4622
4623         } else
4624         if (params->loopback_mode == LOOPBACK_BMAC) {
4625                 vars->link_up = 1;
4626                 vars->line_speed = SPEED_10000;
4627                 vars->duplex = DUPLEX_FULL;
4628                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4629                 vars->mac_type = MAC_TYPE_BMAC;
4630
4631                 vars->phy_flags = PHY_XGXS_FLAG;
4632
4633                 bnx2x_phy_deassert(params, vars->phy_flags);
4634                 /* set bmac loopback */
4635                 bnx2x_bmac_enable(params, vars, 1);
4636
4637                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4638                     params->port*4, 0);
4639         } else if (params->loopback_mode == LOOPBACK_EMAC) {
4640                 vars->link_up = 1;
4641                 vars->line_speed = SPEED_1000;
4642                 vars->duplex = DUPLEX_FULL;
4643                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4644                 vars->mac_type = MAC_TYPE_EMAC;
4645
4646                 vars->phy_flags = PHY_XGXS_FLAG;
4647
4648                 bnx2x_phy_deassert(params, vars->phy_flags);
4649                 /* set bmac loopback */
4650                 bnx2x_emac_enable(params, vars, 1);
4651                 bnx2x_emac_program(params, vars->line_speed,
4652                                               vars->duplex);
4653                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4654                     params->port*4, 0);
4655         } else if ((params->loopback_mode == LOOPBACK_XGXS_10) ||
4656                   (params->loopback_mode == LOOPBACK_EXT_PHY)) {
4657                 vars->link_up = 1;
4658                 vars->line_speed = SPEED_10000;
4659                 vars->duplex = DUPLEX_FULL;
4660                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4661
4662                 vars->phy_flags = PHY_XGXS_FLAG;
4663
4664                 val = REG_RD(bp,
4665                                  NIG_REG_XGXS0_CTRL_PHY_ADDR+
4666                                  params->port*0x18);
4667                 params->phy_addr = (u8)val;
4668
4669                 bnx2x_phy_deassert(params, vars->phy_flags);
4670                 bnx2x_link_initialize(params, vars);
4671
4672                 vars->mac_type = MAC_TYPE_BMAC;
4673
4674                 bnx2x_bmac_enable(params, vars, 0);
4675
4676                 if (params->loopback_mode == LOOPBACK_XGXS_10) {
4677                         /* set 10G XGXS loopback */
4678                         bnx2x_set_xgxs_loopback(params, vars, 1);
4679                 } else {
4680                         /* set external phy loopback */
4681                         bnx2x_ext_phy_loopback(params);
4682                 }
4683                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4684                             params->port*4, 0);
4685         } else
4686         /* No loopback */
4687         {
4688
4689                 bnx2x_phy_deassert(params, vars->phy_flags);
4690                 switch (params->switch_cfg) {
4691                 case SWITCH_CFG_1G:
4692                         vars->phy_flags |= PHY_SERDES_FLAG;
4693                         if ((params->ext_phy_config &
4694                              PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) ==
4695                              PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482) {
4696                                 vars->phy_flags |=
4697                                         PHY_SGMII_FLAG;
4698                         }
4699
4700                         val = REG_RD(bp,
4701                                          NIG_REG_SERDES0_CTRL_PHY_ADDR+
4702                                          params->port*0x10);
4703
4704                         params->phy_addr = (u8)val;
4705
4706                         break;
4707                 case SWITCH_CFG_10G:
4708                         vars->phy_flags |= PHY_XGXS_FLAG;
4709                         val = REG_RD(bp,
4710                                  NIG_REG_XGXS0_CTRL_PHY_ADDR+
4711                                  params->port*0x18);
4712                         params->phy_addr = (u8)val;
4713
4714                         break;
4715                 default:
4716                         DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
4717                         return -EINVAL;
4718                         break;
4719                 }
4720
4721                 bnx2x_link_initialize(params, vars);
4722                 msleep(30);
4723                 bnx2x_link_int_enable(params);
4724         }
4725         return 0;
4726 }
4727
4728 static void bnx2x_8726_reset_phy(struct bnx2x *bp, u8 port, u8 ext_phy_addr)
4729 {
4730         DP(NETIF_MSG_LINK, "bnx2x_8726_reset_phy port %d\n", port);
4731
4732         /* Set serial boot control for external load */
4733         bnx2x_cl45_write(bp, port,
4734                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, ext_phy_addr,
4735                        MDIO_PMA_DEVAD,
4736                        MDIO_PMA_REG_GEN_CTRL, 0x0001);
4737
4738         /* Disable Transmitter */
4739         bnx2x_bcm8726_set_transmitter(bp, port, ext_phy_addr, 0);
4740
4741 }
4742
4743 u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
4744                   u8 reset_ext_phy)
4745 {
4746
4747         struct bnx2x *bp = params->bp;
4748         u32 ext_phy_config = params->ext_phy_config;
4749         u16 hw_led_mode = params->hw_led_mode;
4750         u32 chip_id = params->chip_id;
4751         u8 port = params->port;
4752         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
4753         /* disable attentions */
4754
4755         vars->link_status = 0;
4756         bnx2x_update_mng(params, vars->link_status);
4757         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
4758                      (NIG_MASK_XGXS0_LINK_STATUS |
4759                       NIG_MASK_XGXS0_LINK10G |
4760                       NIG_MASK_SERDES0_LINK_STATUS |
4761                       NIG_MASK_MI_INT));
4762
4763         /* activate nig drain */
4764         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
4765
4766         /* disable nig egress interface */
4767         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
4768         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
4769
4770         /* Stop BigMac rx */
4771         bnx2x_bmac_rx_disable(bp, port);
4772
4773         /* disable emac */
4774         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
4775
4776         msleep(10);
4777         /* The PHY reset is controled by GPIO 1
4778          * Hold it as vars low
4779          */
4780          /* clear link led */
4781         bnx2x_set_led(bp, port, LED_MODE_OFF, 0, hw_led_mode, chip_id);
4782         if (reset_ext_phy) {
4783                 switch (ext_phy_type) {
4784                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4785                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4786                         break;
4787                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4788                         DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
4789                                  "low power mode\n",
4790                                  port);
4791                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4792                                           MISC_REGISTERS_GPIO_OUTPUT_LOW,
4793                                           port);
4794                         break;
4795                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
4796                 {
4797                         u8 ext_phy_addr = ((params->ext_phy_config &
4798                                          PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4799                                          PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4800                         /* Set soft reset */
4801                         bnx2x_8726_reset_phy(bp, params->port, ext_phy_addr);
4802                         break;
4803                 }
4804                 default:
4805                         /* HW reset */
4806                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
4807                                           MISC_REGISTERS_GPIO_OUTPUT_LOW,
4808                                           port);
4809                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4810                                           MISC_REGISTERS_GPIO_OUTPUT_LOW,
4811                                           port);
4812                         DP(NETIF_MSG_LINK, "reset external PHY\n");
4813                 }
4814         }
4815         /* reset the SerDes/XGXS */
4816         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
4817                (0x1ff << (port*16)));
4818
4819         /* reset BigMac */
4820         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
4821                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4822
4823         /* disable nig ingress interface */
4824         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
4825         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
4826         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
4827         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
4828         vars->link_up = 0;
4829         return 0;
4830 }
4831
4832 static u8 bnx2x_update_link_down(struct link_params *params,
4833                                struct link_vars *vars)
4834 {
4835         struct bnx2x *bp = params->bp;
4836         u8 port = params->port;
4837         DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
4838         bnx2x_set_led(bp, port, LED_MODE_OFF,
4839                     0, params->hw_led_mode,
4840                     params->chip_id);
4841
4842         /* indicate no mac active */
4843         vars->mac_type = MAC_TYPE_NONE;
4844
4845         /* update shared memory */
4846         vars->link_status = 0;
4847         vars->line_speed = 0;
4848         bnx2x_update_mng(params, vars->link_status);
4849
4850         /* activate nig drain */
4851         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
4852
4853         /* disable emac */
4854         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
4855
4856         msleep(10);
4857
4858         /* reset BigMac */
4859         bnx2x_bmac_rx_disable(bp, params->port);
4860         REG_WR(bp, GRCBASE_MISC +
4861                    MISC_REGISTERS_RESET_REG_2_CLEAR,
4862                    (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4863         return 0;
4864 }
4865
4866 static u8 bnx2x_update_link_up(struct link_params *params,
4867                              struct link_vars *vars,
4868                              u8 link_10g, u32 gp_status)
4869 {
4870         struct bnx2x *bp = params->bp;
4871         u8 port = params->port;
4872         u8 rc = 0;
4873         vars->link_status |= LINK_STATUS_LINK_UP;
4874         if (link_10g) {
4875                 bnx2x_bmac_enable(params, vars, 0);
4876                 bnx2x_set_led(bp, port, LED_MODE_OPER,
4877                             SPEED_10000, params->hw_led_mode,
4878                             params->chip_id);
4879
4880         } else {
4881                 bnx2x_emac_enable(params, vars, 0);
4882                 rc = bnx2x_emac_program(params, vars->line_speed,
4883                                       vars->duplex);
4884
4885                 /* AN complete? */
4886                 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
4887                         if (!(vars->phy_flags &
4888                               PHY_SGMII_FLAG))
4889                                 bnx2x_set_sgmii_tx_driver(params);
4890                 }
4891         }
4892
4893         /* PBF - link up */
4894         rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
4895                               vars->line_speed);
4896
4897         /* disable drain */
4898         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
4899
4900         /* update shared memory */
4901         bnx2x_update_mng(params, vars->link_status);
4902         msleep(20);
4903         return rc;
4904 }
4905 /* This function should called upon link interrupt */
4906 /* In case vars->link_up, driver needs to
4907         1. Update the pbf
4908         2. Disable drain
4909         3. Update the shared memory
4910         4. Indicate link up
4911         5. Set LEDs
4912    Otherwise,
4913         1. Update shared memory
4914         2. Reset BigMac
4915         3. Report link down
4916         4. Unset LEDs
4917 */
4918 u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
4919 {
4920         struct bnx2x *bp = params->bp;
4921         u8 port = params->port;
4922         u16 gp_status;
4923         u8 link_10g;
4924         u8 ext_phy_link_up, rc = 0;
4925         u32 ext_phy_type;
4926
4927         DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
4928          port,
4929         (vars->phy_flags & PHY_XGXS_FLAG),
4930          REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
4931
4932         DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
4933         REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
4934         REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
4935         REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
4936
4937         DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
4938           REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
4939           REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
4940
4941         /* disable emac */
4942         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
4943
4944         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4945
4946         /* Check external link change only for non-direct */
4947         ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars);
4948
4949         /* Read gp_status */
4950         CL45_RD_OVER_CL22(bp, port, params->phy_addr,
4951                               MDIO_REG_BANK_GP_STATUS,
4952                               MDIO_GP_STATUS_TOP_AN_STATUS1,
4953                               &gp_status);
4954
4955         rc = bnx2x_link_settings_status(params, vars, gp_status);
4956         if (rc != 0)
4957                 return rc;
4958
4959         /* anything 10 and over uses the bmac */
4960         link_10g = ((vars->line_speed == SPEED_10000) ||
4961                     (vars->line_speed == SPEED_12000) ||
4962                     (vars->line_speed == SPEED_12500) ||
4963                     (vars->line_speed == SPEED_13000) ||
4964                     (vars->line_speed == SPEED_15000) ||
4965                     (vars->line_speed == SPEED_16000));
4966
4967         bnx2x_link_int_ack(params, vars, link_10g);
4968
4969         /* In case external phy link is up, and internal link is down
4970         ( not initialized yet probably after link initialization, it needs
4971         to be initialized.
4972         Note that after link down-up as result of cable plug,
4973         the xgxs link would probably become up again without the need to
4974         initialize it*/
4975
4976         if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
4977             (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
4978             (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) &&
4979             (ext_phy_link_up && !vars->phy_link_up))
4980                 bnx2x_init_internal_phy(params, vars);
4981
4982         /* link is up only if both local phy and external phy are up */
4983         vars->link_up = (ext_phy_link_up && vars->phy_link_up);
4984
4985         if (vars->link_up)
4986                 rc = bnx2x_update_link_up(params, vars, link_10g, gp_status);
4987         else
4988                 rc = bnx2x_update_link_down(params, vars);
4989
4990         return rc;
4991 }
4992
4993 static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
4994 {
4995         u8 ext_phy_addr[PORT_MAX];
4996         u16 val;
4997         s8 port;
4998
4999         /* PART1 - Reset both phys */
5000         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
5001                 /* Extract the ext phy address for the port */
5002                 u32 ext_phy_config = REG_RD(bp, shmem_base +
5003                                         offsetof(struct shmem_region,
5004                    dev_info.port_hw_config[port].external_phy_config));
5005
5006                 /* disable attentions */
5007                 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
5008                              (NIG_MASK_XGXS0_LINK_STATUS |
5009                               NIG_MASK_XGXS0_LINK10G |
5010                               NIG_MASK_SERDES0_LINK_STATUS |
5011                               NIG_MASK_MI_INT));
5012
5013                 ext_phy_addr[port] =
5014                         ((ext_phy_config &
5015                               PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
5016                               PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
5017
5018                 /* Need to take the phy out of low power mode in order
5019                         to write to access its registers */
5020                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5021                                   MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
5022
5023                 /* Reset the phy */
5024                 bnx2x_cl45_write(bp, port,
5025                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5026                                ext_phy_addr[port],
5027                                MDIO_PMA_DEVAD,
5028                                MDIO_PMA_REG_CTRL,
5029                                1<<15);
5030         }
5031
5032         /* Add delay of 150ms after reset */
5033         msleep(150);
5034
5035         /* PART2 - Download firmware to both phys */
5036         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
5037                 u16 fw_ver1;
5038
5039                 bnx2x_bcm8073_external_rom_boot(bp, port,
5040                                                       ext_phy_addr[port]);
5041
5042                 bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5043                               ext_phy_addr[port],
5044                               MDIO_PMA_DEVAD,
5045                               MDIO_PMA_REG_ROM_VER1, &fw_ver1);
5046                 if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
5047                         DP(NETIF_MSG_LINK,
5048                                  "bnx2x_8073_common_init_phy port %x:"
5049                                  "Download failed. fw version = 0x%x\n",
5050                                  port, fw_ver1);
5051                         return -EINVAL;
5052                 }
5053
5054                 /* Only set bit 10 = 1 (Tx power down) */
5055                 bnx2x_cl45_read(bp, port,
5056                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5057                               ext_phy_addr[port],
5058                               MDIO_PMA_DEVAD,
5059                               MDIO_PMA_REG_TX_POWER_DOWN, &val);
5060
5061                 /* Phase1 of TX_POWER_DOWN reset */
5062                 bnx2x_cl45_write(bp, port,
5063                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5064                                ext_phy_addr[port],
5065                                MDIO_PMA_DEVAD,
5066                                MDIO_PMA_REG_TX_POWER_DOWN,
5067                                (val | 1<<10));
5068         }
5069
5070         /* Toggle Transmitter: Power down and then up with 600ms
5071            delay between */
5072         msleep(600);
5073
5074         /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
5075         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
5076                 /* Phase2 of POWER_DOWN_RESET*/
5077                 /* Release bit 10 (Release Tx power down) */
5078                 bnx2x_cl45_read(bp, port,
5079                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5080                               ext_phy_addr[port],
5081                               MDIO_PMA_DEVAD,
5082                               MDIO_PMA_REG_TX_POWER_DOWN, &val);
5083
5084                 bnx2x_cl45_write(bp, port,
5085                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5086                                ext_phy_addr[port],
5087                                MDIO_PMA_DEVAD,
5088                                MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
5089                 msleep(15);
5090
5091                 /* Read modify write the SPI-ROM version select register */
5092                 bnx2x_cl45_read(bp, port,
5093                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5094                               ext_phy_addr[port],
5095                               MDIO_PMA_DEVAD,
5096                               MDIO_PMA_REG_EDC_FFE_MAIN, &val);
5097                 bnx2x_cl45_write(bp, port,
5098                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5099                               ext_phy_addr[port],
5100                               MDIO_PMA_DEVAD,
5101                               MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
5102
5103                 /* set GPIO2 back to LOW */
5104                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5105                                   MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
5106         }
5107         return 0;
5108
5109 }
5110
5111
5112 static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base)
5113 {
5114         u8 ext_phy_addr;
5115         u32 val;
5116         s8 port;
5117         /* Use port1 because of the static port-swap */
5118         /* Enable the module detection interrupt */
5119         val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
5120         val |= ((1<<MISC_REGISTERS_GPIO_3)|
5121                 (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
5122         REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
5123
5124         bnx2x_hw_reset(bp, 1);
5125         msleep(5);
5126         for (port = 0; port < PORT_MAX; port++) {
5127                 /* Extract the ext phy address for the port */
5128                 u32 ext_phy_config = REG_RD(bp, shmem_base +
5129                                         offsetof(struct shmem_region,
5130                         dev_info.port_hw_config[port].external_phy_config));
5131
5132                 ext_phy_addr =
5133                         ((ext_phy_config &
5134                               PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
5135                               PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
5136                 DP(NETIF_MSG_LINK, "8726_common_init : ext_phy_addr = 0x%x\n",
5137                          ext_phy_addr);
5138
5139                 bnx2x_8726_reset_phy(bp, port, ext_phy_addr);
5140
5141                 /* Set fault module detected LED on */
5142                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
5143                                   MISC_REGISTERS_GPIO_HIGH,
5144                                   port);
5145         }
5146
5147         return 0;
5148 }
5149
5150 u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
5151 {
5152         u8 rc = 0;
5153         u32 ext_phy_type;
5154
5155         DP(NETIF_MSG_LINK, "bnx2x_common_init_phy\n");
5156
5157         /* Read the ext_phy_type for arbitrary port(0) */
5158         ext_phy_type = XGXS_EXT_PHY_TYPE(
5159                         REG_RD(bp, shmem_base +
5160                            offsetof(struct shmem_region,
5161                              dev_info.port_hw_config[0].external_phy_config)));
5162
5163         switch (ext_phy_type) {
5164         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
5165         {
5166                 rc = bnx2x_8073_common_init_phy(bp, shmem_base);
5167                 break;
5168         }
5169         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
5170                 /* GPIO1 affects both ports, so there's need to pull
5171                 it for single port alone */
5172                 rc = bnx2x_8726_common_init_phy(bp, shmem_base);
5173
5174                 break;
5175         default:
5176                 DP(NETIF_MSG_LINK,
5177                          "bnx2x_common_init_phy: ext_phy 0x%x not required\n",
5178                          ext_phy_type);
5179                 break;
5180         }
5181
5182         return rc;
5183 }
5184
5185
5186
5187 static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
5188 {
5189         u16 val, cnt;
5190
5191         bnx2x_cl45_read(bp, port,
5192                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5193                       phy_addr,
5194                       MDIO_PMA_DEVAD,
5195                       MDIO_PMA_REG_7101_RESET, &val);
5196
5197         for (cnt = 0; cnt < 10; cnt++) {
5198                 msleep(50);
5199                 /* Writes a self-clearing reset */
5200                 bnx2x_cl45_write(bp, port,
5201                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5202                                phy_addr,
5203                                MDIO_PMA_DEVAD,
5204                                MDIO_PMA_REG_7101_RESET,
5205                                (val | (1<<15)));
5206                 /* Wait for clear */
5207                 bnx2x_cl45_read(bp, port,
5208                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5209                               phy_addr,
5210                               MDIO_PMA_DEVAD,
5211                               MDIO_PMA_REG_7101_RESET, &val);
5212
5213                 if ((val & (1<<15)) == 0)
5214                         break;
5215         }
5216 }
5217 #define RESERVED_SIZE 256
5218 /* max application is 160K bytes - data at end of RAM */
5219 #define MAX_APP_SIZE (160*1024 - RESERVED_SIZE)
5220
5221 /* Header is 14 bytes */
5222 #define HEADER_SIZE 14
5223 #define DATA_OFFSET HEADER_SIZE
5224
5225 #define SPI_START_TRANSFER(bp, port, ext_phy_addr) \
5226         bnx2x_cl45_write(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, \
5227                         ext_phy_addr, \
5228                         MDIO_PCS_DEVAD, \
5229                         MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 1)
5230
5231 /* Programs an image to DSP's flash via the SPI port*/
5232 static u8 bnx2x_sfx7101_flash_download(struct bnx2x *bp, u8 port,
5233                                      u8 ext_phy_addr,
5234                                      char data[], u32 size)
5235 {
5236         const u16 num_trans = size/4; /* 4 bytes can be sent at a time */
5237         /* Doesn't include last trans!*/
5238         const u16 last_trans_size = size%4; /* Num bytes on last trans */
5239         u16 trans_cnt, byte_cnt;
5240         u32 data_index;
5241         u16 tmp;
5242         u16 code_started = 0;
5243         u16 image_revision1, image_revision2;
5244         u16 cnt;
5245
5246         DP(NETIF_MSG_LINK, "bnx2x_sfx7101_flash_download file_size=%d\n", size);
5247         /* Going to flash*/
5248         if ((size-HEADER_SIZE) > MAX_APP_SIZE) {
5249                 /* This very often will be the case, because the image is built
5250                 with 160Kbytes size whereas the total image size must actually
5251                 be 160Kbytes-RESERVED_SIZE */
5252                 DP(NETIF_MSG_LINK, "Warning, file size was %d bytes "
5253                          "truncated to %d bytes\n", size, MAX_APP_SIZE);
5254                 size = MAX_APP_SIZE+HEADER_SIZE;
5255         }
5256         DP(NETIF_MSG_LINK, "File version is %c%c\n", data[0x14e], data[0x14f]);
5257         DP(NETIF_MSG_LINK, "          %c%c\n", data[0x150], data[0x151]);
5258         /* Put the DSP in download mode by setting FLASH_CFG[2] to 1
5259            and issuing a reset.*/
5260
5261         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
5262                           MISC_REGISTERS_GPIO_HIGH, port);
5263
5264         bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
5265
5266         /* wait 0.5 sec */
5267         for (cnt = 0; cnt < 100; cnt++)
5268                 msleep(5);
5269
5270         /* Make sure we can access the DSP
5271            And it's in the correct mode (waiting for download) */
5272
5273         bnx2x_cl45_read(bp, port,
5274                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5275                       ext_phy_addr,
5276                       MDIO_PCS_DEVAD,
5277                       MDIO_PCS_REG_7101_DSP_ACCESS, &tmp);
5278
5279         if (tmp != 0x000A) {
5280                 DP(NETIF_MSG_LINK, "DSP is not in waiting on download mode. "
5281                          "Expected 0x000A, read 0x%04X\n", tmp);
5282                 DP(NETIF_MSG_LINK, "Download failed\n");
5283                 return -EINVAL;
5284         }
5285
5286         /* Mux the SPI interface away from the internal processor */
5287         bnx2x_cl45_write(bp, port,
5288                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5289                        ext_phy_addr,
5290                        MDIO_PCS_DEVAD,
5291                        MDIO_PCS_REG_7101_SPI_MUX, 1);
5292
5293         /* Reset the SPI port */
5294         bnx2x_cl45_write(bp, port,
5295                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5296                        ext_phy_addr,
5297                        MDIO_PCS_DEVAD,
5298                        MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
5299         bnx2x_cl45_write(bp, port,
5300                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5301                        ext_phy_addr,
5302                        MDIO_PCS_DEVAD,
5303                        MDIO_PCS_REG_7101_SPI_CTRL_ADDR,
5304                        (1<<MDIO_PCS_REG_7101_SPI_RESET_BIT));
5305         bnx2x_cl45_write(bp, port,
5306                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5307                        ext_phy_addr,
5308                        MDIO_PCS_DEVAD,
5309                        MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
5310
5311         /* Erase the flash */
5312         bnx2x_cl45_write(bp, port,
5313                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5314                        ext_phy_addr,
5315                        MDIO_PCS_DEVAD,
5316                        MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5317                        MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
5318
5319         bnx2x_cl45_write(bp, port,
5320                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5321                        ext_phy_addr,
5322                        MDIO_PCS_DEVAD,
5323                        MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5324                        1);
5325
5326         SPI_START_TRANSFER(bp, port, ext_phy_addr);
5327         bnx2x_cl45_write(bp, port,
5328                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5329                        ext_phy_addr,
5330                        MDIO_PCS_DEVAD,
5331                        MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5332                        MDIO_PCS_REG_7101_SPI_FIFO_ADDR_BULK_ERASE_CMD);
5333
5334         bnx2x_cl45_write(bp, port,
5335                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5336                        ext_phy_addr,
5337                        MDIO_PCS_DEVAD,
5338                        MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5339                        1);
5340         SPI_START_TRANSFER(bp, port, ext_phy_addr);
5341
5342         /* Wait 10 seconds, the maximum time for the erase to complete */
5343         DP(NETIF_MSG_LINK, "Erasing flash, this takes 10 seconds...\n");
5344         for (cnt = 0; cnt < 1000; cnt++)
5345                 msleep(10);
5346
5347         DP(NETIF_MSG_LINK, "Downloading flash, please wait...\n");
5348         data_index = 0;
5349         for (trans_cnt = 0; trans_cnt < num_trans; trans_cnt++) {
5350                 bnx2x_cl45_write(bp, port,
5351                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5352                              ext_phy_addr,
5353                              MDIO_PCS_DEVAD,
5354                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5355                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
5356
5357                 bnx2x_cl45_write(bp, port,
5358                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5359                                ext_phy_addr,
5360                                MDIO_PCS_DEVAD,
5361                                MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5362                                1);
5363                 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5364
5365                 bnx2x_cl45_write(bp, port,
5366                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5367                                ext_phy_addr,
5368                                MDIO_PCS_DEVAD,
5369                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5370                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
5371
5372                 /* Bits 23-16 of address */
5373                 bnx2x_cl45_write(bp, port,
5374                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5375                                ext_phy_addr,
5376                                MDIO_PCS_DEVAD,
5377                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5378                                (data_index>>16));
5379                 /* Bits 15-8 of address */
5380                 bnx2x_cl45_write(bp, port,
5381                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5382                                ext_phy_addr,
5383                                MDIO_PCS_DEVAD,
5384                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5385                                (data_index>>8));
5386
5387                 /* Bits 7-0 of address */
5388                 bnx2x_cl45_write(bp, port,
5389                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5390                                ext_phy_addr,
5391                                MDIO_PCS_DEVAD,
5392                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5393                                ((u16)data_index));
5394
5395                 byte_cnt = 0;
5396                 while (byte_cnt < 4 && data_index < size) {
5397                         bnx2x_cl45_write(bp, port,
5398                                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5399                                        ext_phy_addr,
5400                                MDIO_PCS_DEVAD,
5401                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5402                                data[data_index++]);
5403                         byte_cnt++;
5404                 }
5405
5406                 bnx2x_cl45_write(bp, port,
5407                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5408                                ext_phy_addr,
5409                                MDIO_PCS_DEVAD,
5410                                MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5411                                byte_cnt+4);
5412
5413                 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5414                 msleep(5); /* Wait 5 ms minimum between transs */
5415
5416                 /* Let the user know something's going on.*/
5417                 /* a pacifier ever 4K */
5418                 if ((data_index % 1023) == 0)
5419                         DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
5420         }
5421
5422         DP(NETIF_MSG_LINK, "\n");
5423         /* Transfer the last block if there is data remaining */
5424         if (last_trans_size) {
5425                 bnx2x_cl45_write(bp, port,
5426                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5427                         ext_phy_addr,
5428                         MDIO_PCS_DEVAD,
5429                         MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5430                         MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
5431
5432                 bnx2x_cl45_write(bp, port,
5433                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5434                                ext_phy_addr,
5435                                MDIO_PCS_DEVAD,
5436                                MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5437                                1);
5438
5439                 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5440
5441                 bnx2x_cl45_write(bp, port,
5442                              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5443                              ext_phy_addr,
5444                              MDIO_PCS_DEVAD,
5445                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5446                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
5447
5448                 /* Bits 23-16 of address */
5449                 bnx2x_cl45_write(bp, port,
5450                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5451                                ext_phy_addr,
5452                                MDIO_PCS_DEVAD,
5453                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5454                                (data_index>>16));
5455                 /* Bits 15-8 of address */
5456                 bnx2x_cl45_write(bp, port,
5457                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5458                                ext_phy_addr,
5459                                MDIO_PCS_DEVAD,
5460                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5461                                (data_index>>8));
5462
5463                 /* Bits 7-0 of address */
5464                 bnx2x_cl45_write(bp, port,
5465                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5466                                ext_phy_addr,
5467                                MDIO_PCS_DEVAD,
5468                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5469                                ((u16)data_index));
5470
5471                 byte_cnt = 0;
5472                 while (byte_cnt < last_trans_size && data_index < size) {
5473                         /* Bits 7-0 of address */
5474                         bnx2x_cl45_write(bp, port,
5475                                 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5476                                 ext_phy_addr,
5477                                 MDIO_PCS_DEVAD,
5478                                 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5479                                 data[data_index++]);
5480                         byte_cnt++;
5481                 }
5482
5483                 bnx2x_cl45_write(bp, port,
5484                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5485                                ext_phy_addr,
5486                                MDIO_PCS_DEVAD,
5487                                MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5488                                byte_cnt+4);
5489
5490                 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5491         }
5492
5493         /* DSP Remove Download Mode */
5494         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
5495                           MISC_REGISTERS_GPIO_LOW, port);
5496
5497         bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
5498
5499         /* wait 0.5 sec to allow it to run */
5500         for (cnt = 0; cnt < 100; cnt++)
5501                 msleep(5);
5502
5503         bnx2x_hw_reset(bp, port);
5504
5505         for (cnt = 0; cnt < 100; cnt++)
5506                 msleep(5);
5507
5508         /* Check that the code is started. In case the download
5509         checksum failed, the code won't be started. */
5510         bnx2x_cl45_read(bp, port,
5511                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5512                       ext_phy_addr,
5513                       MDIO_PCS_DEVAD,
5514                       MDIO_PCS_REG_7101_DSP_ACCESS,
5515                       &tmp);
5516
5517         code_started = (tmp & (1<<4));
5518         if (!code_started) {
5519                 DP(NETIF_MSG_LINK, "Download failed. Please check file.\n");
5520                 return -EINVAL;
5521         }
5522
5523         /* Verify that the file revision is now equal to the image
5524         revision within the DSP */
5525         bnx2x_cl45_read(bp, port,
5526                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5527                       ext_phy_addr,
5528                       MDIO_PMA_DEVAD,
5529                       MDIO_PMA_REG_7101_VER1,
5530                       &image_revision1);
5531
5532         bnx2x_cl45_read(bp, port,
5533                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5534                       ext_phy_addr,
5535                       MDIO_PMA_DEVAD,
5536                       MDIO_PMA_REG_7101_VER2,
5537                       &image_revision2);
5538
5539         if (data[0x14e] != (image_revision2&0xFF) ||
5540             data[0x14f] != ((image_revision2&0xFF00)>>8) ||
5541             data[0x150] != (image_revision1&0xFF) ||
5542             data[0x151] != ((image_revision1&0xFF00)>>8)) {
5543                 DP(NETIF_MSG_LINK, "Download failed.\n");
5544                 return -EINVAL;
5545         }
5546         DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
5547         return 0;
5548 }
5549
5550 u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
5551                       u8 driver_loaded, char data[], u32 size)
5552 {
5553         u8 rc = 0;
5554         u32 ext_phy_type;
5555         u8 ext_phy_addr;
5556         ext_phy_addr = ((ext_phy_config &
5557                         PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
5558                         PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
5559
5560         ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
5561
5562         switch (ext_phy_type) {
5563         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
5564         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
5565         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
5566         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
5567                 DP(NETIF_MSG_LINK,
5568                         "Flash download not supported for this ext phy\n");
5569                 rc = -EINVAL;
5570                 break;
5571         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
5572                 /* Take ext phy out of reset */
5573                 if (!driver_loaded)
5574                         bnx2x_turn_on_ef(bp, port, ext_phy_addr, ext_phy_type);
5575                 rc = bnx2x_sfx7101_flash_download(bp, port, ext_phy_addr,
5576                                                 data, size);
5577                 if (!driver_loaded)
5578                         bnx2x_turn_off_sf(bp, port);
5579                 break;
5580         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
5581         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
5582         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
5583         default:
5584                 DP(NETIF_MSG_LINK, "Invalid ext phy type\n");
5585                 rc = -EINVAL;
5586                 break;
5587         }
5588         return rc;
5589 }
5590