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