bnx2x: Supporting new BCM8726 FW
[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
1927                         /* Restore normal power mode*/
1928                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1929                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1930                                           params->port);
1931
1932                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1933                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1934                                           params->port);
1935
1936                         DP(NETIF_MSG_LINK, "XGXS 8073\n");
1937                         }
1938                         break;
1939
1940                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
1941                         DP(NETIF_MSG_LINK, "XGXS SFX7101\n");
1942
1943                         /* Restore normal power mode*/
1944                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1945                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1946                                           params->port);
1947
1948                         /* HW reset */
1949                         bnx2x_hw_reset(bp, params->port);
1950
1951                         break;
1952
1953                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
1954
1955                         /* Restore normal power mode*/
1956                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1957                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1958                                           params->port);
1959
1960                         /* HW reset */
1961                         bnx2x_hw_reset(bp, params->port);
1962
1963                         bnx2x_cl45_write(bp, params->port,
1964                                        ext_phy_type,
1965                                        ext_phy_addr,
1966                                        MDIO_PMA_DEVAD,
1967                                        MDIO_PMA_REG_CTRL,
1968                                        1<<15);
1969                         break;
1970                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
1971                         DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n");
1972                         break;
1973
1974                 default:
1975                         DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
1976                            params->ext_phy_config);
1977                         break;
1978                 }
1979
1980         } else { /* SerDes */
1981                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
1982                 switch (ext_phy_type) {
1983                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
1984                         DP(NETIF_MSG_LINK, "SerDes Direct\n");
1985                         break;
1986
1987                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
1988                         DP(NETIF_MSG_LINK, "SerDes 5482\n");
1989                         bnx2x_hw_reset(bp, params->port);
1990                         break;
1991
1992                 default:
1993                         DP(NETIF_MSG_LINK,
1994                                  "BAD SerDes ext_phy_config 0x%x\n",
1995                                  params->ext_phy_config);
1996                         break;
1997                 }
1998         }
1999 }
2000
2001
2002 static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port,
2003                                     u32 shmem_base, u32 spirom_ver)
2004 {
2005         DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x\n",
2006                  (u16)(spirom_ver>>16), (u16)spirom_ver);
2007         REG_WR(bp, shmem_base +
2008                    offsetof(struct shmem_region,
2009                             port_mb[port].ext_phy_fw_version),
2010                         spirom_ver);
2011 }
2012
2013 static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp, u8 port,
2014                                     u32 ext_phy_type, u8 ext_phy_addr,
2015                                     u32 shmem_base)
2016 {
2017         u16 fw_ver1, fw_ver2;
2018         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
2019                       MDIO_PMA_REG_ROM_VER1, &fw_ver1);
2020         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
2021                       MDIO_PMA_REG_ROM_VER2, &fw_ver2);
2022         bnx2x_save_spirom_version(bp, port, shmem_base,
2023                                 (u32)(fw_ver1<<16 | fw_ver2));
2024 }
2025
2026 static void bnx2x_bcm8072_external_rom_boot(struct link_params *params)
2027 {
2028         struct bnx2x *bp = params->bp;
2029         u8 port = params->port;
2030         u8 ext_phy_addr = ((params->ext_phy_config &
2031                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2032                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2033         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2034
2035         /* Need to wait 200ms after reset */
2036         msleep(200);
2037         /* Boot port from external ROM
2038          * Set ser_boot_ctl bit in the MISC_CTRL1 register
2039          */
2040         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2041                             MDIO_PMA_DEVAD,
2042                             MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2043
2044         /* Reset internal microprocessor */
2045         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2046                           MDIO_PMA_DEVAD,
2047                           MDIO_PMA_REG_GEN_CTRL,
2048                           MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2049         /* set micro reset = 0 */
2050         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2051                             MDIO_PMA_DEVAD,
2052                             MDIO_PMA_REG_GEN_CTRL,
2053                             MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2054         /* Reset internal microprocessor */
2055         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2056                           MDIO_PMA_DEVAD,
2057                           MDIO_PMA_REG_GEN_CTRL,
2058                           MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2059         /* wait for 100ms for code download via SPI port */
2060         msleep(100);
2061
2062         /* Clear ser_boot_ctl bit */
2063         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2064                             MDIO_PMA_DEVAD,
2065                             MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2066         /* Wait 100ms */
2067         msleep(100);
2068
2069         bnx2x_save_bcm_spirom_ver(bp, port,
2070                                 ext_phy_type,
2071                                 ext_phy_addr,
2072                                 params->shmem_base);
2073 }
2074
2075 static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
2076 {
2077         /* This is only required for 8073A1, version 102 only */
2078
2079         struct bnx2x *bp = params->bp;
2080         u8 ext_phy_addr = ((params->ext_phy_config &
2081                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2082                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2083         u16 val;
2084
2085         /* Read 8073 HW revision*/
2086         bnx2x_cl45_read(bp, params->port,
2087                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2088                       ext_phy_addr,
2089                       MDIO_PMA_DEVAD,
2090                       MDIO_PMA_REG_8073_CHIP_REV, &val);
2091
2092         if (val != 1) {
2093                 /* No need to workaround in 8073 A1 */
2094                 return 0;
2095         }
2096
2097         bnx2x_cl45_read(bp, params->port,
2098                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2099                       ext_phy_addr,
2100                       MDIO_PMA_DEVAD,
2101                       MDIO_PMA_REG_ROM_VER2, &val);
2102
2103         /* SNR should be applied only for version 0x102 */
2104         if (val != 0x102)
2105                 return 0;
2106
2107         return 1;
2108 }
2109
2110 static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
2111 {
2112         struct bnx2x *bp = params->bp;
2113         u8 ext_phy_addr = ((params->ext_phy_config &
2114                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2115                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2116         u16 val, cnt, cnt1 ;
2117
2118         bnx2x_cl45_read(bp, params->port,
2119                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2120                       ext_phy_addr,
2121                       MDIO_PMA_DEVAD,
2122                       MDIO_PMA_REG_8073_CHIP_REV, &val);
2123
2124         if (val > 0) {
2125                 /* No need to workaround in 8073 A1 */
2126                 return 0;
2127         }
2128         /* XAUI workaround in 8073 A0: */
2129
2130         /* After loading the boot ROM and restarting Autoneg,
2131         poll Dev1, Reg $C820: */
2132
2133         for (cnt = 0; cnt < 1000; cnt++) {
2134                 bnx2x_cl45_read(bp, params->port,
2135                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2136                               ext_phy_addr,
2137                               MDIO_PMA_DEVAD,
2138                               MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
2139                               &val);
2140                   /* If bit [14] = 0 or bit [13] = 0, continue on with
2141                    system initialization (XAUI work-around not required,
2142                     as these bits indicate 2.5G or 1G link up). */
2143                 if (!(val & (1<<14)) || !(val & (1<<13))) {
2144                         DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
2145                         return 0;
2146                 } else if (!(val & (1<<15))) {
2147                         DP(NETIF_MSG_LINK, "clc bit 15 went off\n");
2148                          /* If bit 15 is 0, then poll Dev1, Reg $C841 until
2149                           it's MSB (bit 15) goes to 1 (indicating that the
2150                           XAUI workaround has completed),
2151                           then continue on with system initialization.*/
2152                         for (cnt1 = 0; cnt1 < 1000; cnt1++) {
2153                                 bnx2x_cl45_read(bp, params->port,
2154                                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2155                                         ext_phy_addr,
2156                                         MDIO_PMA_DEVAD,
2157                                         MDIO_PMA_REG_8073_XAUI_WA, &val);
2158                                 if (val & (1<<15)) {
2159                                         DP(NETIF_MSG_LINK,
2160                                           "XAUI workaround has completed\n");
2161                                         return 0;
2162                                  }
2163                                  msleep(3);
2164                         }
2165                         break;
2166                 }
2167                 msleep(3);
2168         }
2169         DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
2170         return -EINVAL;
2171
2172 }
2173
2174 static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port,
2175                                           u8 ext_phy_addr, u32 shmem_base)
2176 {
2177         /* Boot port from external ROM  */
2178         /* EDC grst */
2179         bnx2x_cl45_write(bp, port,
2180                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2181                        ext_phy_addr,
2182                        MDIO_PMA_DEVAD,
2183                        MDIO_PMA_REG_GEN_CTRL,
2184                        0x0001);
2185
2186         /* ucode reboot and rst */
2187         bnx2x_cl45_write(bp, port,
2188                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2189                        ext_phy_addr,
2190                        MDIO_PMA_DEVAD,
2191                        MDIO_PMA_REG_GEN_CTRL,
2192                        0x008c);
2193
2194         bnx2x_cl45_write(bp, port,
2195                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2196                        ext_phy_addr,
2197                        MDIO_PMA_DEVAD,
2198                        MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2199
2200         /* Reset internal microprocessor */
2201         bnx2x_cl45_write(bp, port,
2202                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2203                        ext_phy_addr,
2204                        MDIO_PMA_DEVAD,
2205                        MDIO_PMA_REG_GEN_CTRL,
2206                        MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2207
2208         /* Release srst bit */
2209         bnx2x_cl45_write(bp, port,
2210                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2211                        ext_phy_addr,
2212                        MDIO_PMA_DEVAD,
2213                        MDIO_PMA_REG_GEN_CTRL,
2214                        MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2215
2216         /* wait for 100ms for code download via SPI port */
2217         msleep(100);
2218
2219         /* Clear ser_boot_ctl bit */
2220         bnx2x_cl45_write(bp, port,
2221                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2222                        ext_phy_addr,
2223                        MDIO_PMA_DEVAD,
2224                        MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2225
2226         bnx2x_save_bcm_spirom_ver(bp, port,
2227                                 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2228                                 ext_phy_addr,
2229                                 shmem_base);
2230 }
2231
2232 static void bnx2x_bcm8726_external_rom_boot(struct link_params *params)
2233 {
2234         struct bnx2x *bp = params->bp;
2235         u8 port = params->port;
2236         u8 ext_phy_addr = ((params->ext_phy_config &
2237                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2238                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2239         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2240
2241         /* Need to wait 100ms after reset */
2242         msleep(100);
2243
2244         /* Set serial boot control for external load */
2245         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2246                        MDIO_PMA_DEVAD,
2247                        MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2248
2249         /* Micro controller re-boot */
2250         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2251                        MDIO_PMA_DEVAD,
2252                        MDIO_PMA_REG_GEN_CTRL,
2253                        MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2254
2255         /* Set soft reset */
2256         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2257                        MDIO_PMA_DEVAD,
2258                        MDIO_PMA_REG_GEN_CTRL,
2259                        MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2260
2261         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2262                        MDIO_PMA_DEVAD,
2263                        MDIO_PMA_REG_GEN_CTRL2,
2264                        0x73A0);
2265
2266         /* Clear soft reset.
2267         Will automatically reset micro-controller re-boot */
2268         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2269                        MDIO_PMA_DEVAD,
2270                        MDIO_PMA_REG_GEN_CTRL,
2271                        MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2272
2273         /* wait for 150ms for microcode load */
2274         msleep(150);
2275
2276         /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
2277         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2278                        MDIO_PMA_DEVAD,
2279                        MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2280
2281         msleep(200);
2282         bnx2x_save_bcm_spirom_ver(bp, port,
2283                                 ext_phy_type,
2284                                 ext_phy_addr,
2285                                 params->shmem_base);
2286 }
2287
2288 static void bnx2x_bcm8726_set_transmitter(struct bnx2x *bp, u8 port,
2289                                         u8 ext_phy_addr, u8 tx_en)
2290 {
2291         u16 val;
2292         DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n",
2293                  tx_en, port);
2294         /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
2295         bnx2x_cl45_read(bp, port,
2296                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2297                       ext_phy_addr,
2298                       MDIO_PMA_DEVAD,
2299                       MDIO_PMA_REG_PHY_IDENTIFIER,
2300                       &val);
2301
2302         if (tx_en)
2303                 val &= ~(1<<15);
2304         else
2305                 val |= (1<<15);
2306
2307         bnx2x_cl45_write(bp, port,
2308                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2309                        ext_phy_addr,
2310                        MDIO_PMA_DEVAD,
2311                        MDIO_PMA_REG_PHY_IDENTIFIER,
2312                        val);
2313 }
2314
2315
2316 static u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr,
2317                                      u8 byte_cnt, u8 *o_buf) {
2318         struct bnx2x *bp = params->bp;
2319         u16 val, i;
2320         u8 port = params->port;
2321         u8 ext_phy_addr = ((params->ext_phy_config &
2322                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2323                            PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2324         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2325         if (byte_cnt > 16) {
2326                 DP(NETIF_MSG_LINK, "Reading from eeprom is"
2327                             " is limited to 0xf\n");
2328                 return -EINVAL;
2329         }
2330         /* Set the read command byte count */
2331         bnx2x_cl45_write(bp, port,
2332                        ext_phy_type,
2333                        ext_phy_addr,
2334                        MDIO_PMA_DEVAD,
2335                        MDIO_PMA_REG_8726_TWO_WIRE_BYTE_CNT,
2336                        (byte_cnt | 0xa000));
2337
2338         /* Set the read command address */
2339         bnx2x_cl45_write(bp, port,
2340                        ext_phy_type,
2341                        ext_phy_addr,
2342                        MDIO_PMA_DEVAD,
2343                        MDIO_PMA_REG_8726_TWO_WIRE_MEM_ADDR,
2344                        addr);
2345
2346         /* Activate read command */
2347         bnx2x_cl45_write(bp, port,
2348                        ext_phy_type,
2349                        ext_phy_addr,
2350                        MDIO_PMA_DEVAD,
2351                        MDIO_PMA_REG_8726_TWO_WIRE_CTRL,
2352                        0x2c0f);
2353
2354         /* Wait up to 500us for command complete status */
2355         for (i = 0; i < 100; i++) {
2356                 bnx2x_cl45_read(bp, port,
2357                               ext_phy_type,
2358                               ext_phy_addr,
2359                               MDIO_PMA_DEVAD,
2360                               MDIO_PMA_REG_8726_TWO_WIRE_CTRL, &val);
2361                 if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) ==
2362                     MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE)
2363                         break;
2364                 udelay(5);
2365         }
2366
2367         if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) !=
2368                     MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE) {
2369                 DP(NETIF_MSG_LINK,
2370                          "Got bad status 0x%x when reading from SFP+ EEPROM\n",
2371                          (val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK));
2372                 return -EINVAL;
2373         }
2374
2375         /* Read the buffer */
2376         for (i = 0; i < byte_cnt; i++) {
2377                 bnx2x_cl45_read(bp, port,
2378                               ext_phy_type,
2379                               ext_phy_addr,
2380                               MDIO_PMA_DEVAD,
2381                               MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
2382                 o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
2383         }
2384
2385         for (i = 0; i < 100; i++) {
2386                 bnx2x_cl45_read(bp, port,
2387                               ext_phy_type,
2388                               ext_phy_addr,
2389                               MDIO_PMA_DEVAD,
2390                               MDIO_PMA_REG_8726_TWO_WIRE_CTRL, &val);
2391                 if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) ==
2392                     MDIO_PMA_REG_8726_TWO_WIRE_STATUS_IDLE)
2393                         return 0;;
2394                 msleep(1);
2395         }
2396         return -EINVAL;
2397 }
2398
2399
2400 static u8 bnx2x_get_sfp_module_type(struct link_params *params,
2401                                   u8 *module_type)
2402 {
2403         struct bnx2x *bp = params->bp;
2404         u8 val;
2405         *module_type = SFP_MODULE_TYPE_UNKNOWN;
2406
2407         /* First check for copper cable */
2408         if (bnx2x_read_sfp_module_eeprom(params,
2409                                        SFP_EEPROM_CON_TYPE_ADDR,
2410                                        1,
2411                                        &val) != 0) {
2412                 DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM");
2413                 return -EINVAL;
2414         }
2415
2416         switch (val) {
2417         case SFP_EEPROM_CON_TYPE_VAL_COPPER:
2418         {
2419                 u8 copper_module_type;
2420                 /* Check if its active cable( includes SFP+ module)
2421                 of passive cable*/
2422                 if (bnx2x_read_sfp_module_eeprom(params,
2423                                                SFP_EEPROM_FC_TX_TECH_ADDR,
2424                                                1,
2425                                                &copper_module_type) !=
2426                     0) {
2427                         DP(NETIF_MSG_LINK,
2428                                 "Failed to read copper-cable-type"
2429                                 " from SFP+ EEPROM\n");
2430                         return -EINVAL;
2431                 }
2432
2433                 if (copper_module_type &
2434                     SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
2435                         DP(NETIF_MSG_LINK, "Active Copper cable detected\n");
2436                         *module_type = SFP_MODULE_TYPE_ACTIVE_COPPER_CABLE;
2437                 } else if (copper_module_type &
2438                         SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
2439                                 DP(NETIF_MSG_LINK, "Passive Copper"
2440                                             " cable detected\n");
2441                                 *module_type =
2442                                       SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE;
2443                 } else {
2444                         DP(NETIF_MSG_LINK, "Unknown copper-cable-"
2445                                      "type 0x%x !!!\n", copper_module_type);
2446                         return -EINVAL;
2447                 }
2448                 break;
2449         }
2450         case SFP_EEPROM_CON_TYPE_VAL_LC:
2451                 DP(NETIF_MSG_LINK, "Optic module detected\n");
2452                 *module_type = SFP_MODULE_TYPE_LC;
2453                 break;
2454
2455         default:
2456                 DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n",
2457                          val);
2458                 return -EINVAL;
2459         }
2460         return 0;
2461 }
2462
2463
2464 /* This function read the relevant field from the module ( SFP+ ),
2465         and verify it is compliant with this board */
2466 static u8 bnx2x_verify_sfp_module(struct link_params *params,
2467                                 u8 module_type)
2468 {
2469         struct bnx2x *bp = params->bp;
2470         u8 *str_p, *tmp_buf;
2471         u16 i;
2472
2473 #define COMPLIANCE_STR_CNT 6
2474         u8 *compliance_str[] = {"Broadcom", "JDSU", "Molex Inc", "PICOLIGHT",
2475                 "FINISAR CORP.   ", "Amphenol"};
2476         u8 buf[SFP_EEPROM_VENDOR_NAME_SIZE];
2477         /* Passive Copper cables are allowed to participate,
2478         since the module is hardwired to the copper cable */
2479
2480         if (!(params->feature_config_flags &
2481              FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED)) {
2482                 DP(NETIF_MSG_LINK, "NOT enforcing module verification\n");
2483                 return 0;
2484         }
2485
2486         if (module_type != SFP_MODULE_TYPE_LC) {
2487                 DP(NETIF_MSG_LINK, "No need to verify copper cable\n");
2488                 return 0;
2489         }
2490
2491         /* In case of non copper cable or Active copper cable,
2492                 verify that the SFP+ module is compliant with this board*/
2493         if (bnx2x_read_sfp_module_eeprom(params,
2494                                        SFP_EEPROM_VENDOR_NAME_ADDR,
2495                                        SFP_EEPROM_VENDOR_NAME_SIZE,
2496                                        buf) != 0) {
2497                 DP(NETIF_MSG_LINK, "Failed to read Vendor-Name from"
2498                             " module EEPROM\n");
2499                 return -EINVAL;
2500         }
2501         for (i = 0; i < COMPLIANCE_STR_CNT; i++) {
2502                 str_p = compliance_str[i];
2503                 tmp_buf = buf;
2504                 while (*str_p) {
2505                         if ((u8)(*tmp_buf) != (u8)(*str_p))
2506                                 break;
2507                         str_p++;
2508                         tmp_buf++;
2509                 }
2510
2511                 if (!(*str_p)) {
2512                         DP(NETIF_MSG_LINK, "SFP+ Module verified, "
2513                                      "index=%x\n", i);
2514                         return 0;
2515                 }
2516         }
2517         DP(NETIF_MSG_LINK, "Incompliant SFP+ module. Disable module !!!\n");
2518         return -EINVAL;
2519 }
2520
2521
2522 static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params,
2523                                         u8 module_type)
2524 {
2525         struct bnx2x *bp = params->bp;
2526         u8 port = params->port;
2527         u8 options[SFP_EEPROM_OPTIONS_SIZE];
2528         u8 limiting_mode;
2529         u8 ext_phy_addr = ((params->ext_phy_config &
2530                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2531                            PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2532         u16 cur_limiting_mode;
2533         if (bnx2x_read_sfp_module_eeprom(params,
2534                                        SFP_EEPROM_OPTIONS_ADDR,
2535                                        SFP_EEPROM_OPTIONS_SIZE,
2536                                        options) != 0) {
2537                 DP(NETIF_MSG_LINK, "Failed to read Option field from"
2538                             " module EEPROM\n");
2539                 return -EINVAL;
2540         }
2541         limiting_mode = !(options[0] &
2542                           SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK);
2543
2544         bnx2x_cl45_read(bp, port,
2545                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2546                       ext_phy_addr,
2547                       MDIO_PMA_DEVAD,
2548                       MDIO_PMA_REG_ROM_VER2,
2549                       &cur_limiting_mode);
2550         DP(NETIF_MSG_LINK, "Current Limiting mode is 0x%x\n",
2551                  cur_limiting_mode);
2552
2553         if (limiting_mode &&
2554             (module_type != SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE)) {
2555                 DP(NETIF_MSG_LINK,
2556                          "Module options = 0x%x.Setting LIMITING MODE\n",
2557                          options[0]);
2558                 bnx2x_cl45_write(bp, port,
2559                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2560                                ext_phy_addr,
2561                                MDIO_PMA_DEVAD,
2562                                MDIO_PMA_REG_ROM_VER2,
2563                                SFP_LIMITING_MODE_VALUE);
2564         } else { /* LRM mode ( default )*/
2565
2566                 DP(NETIF_MSG_LINK, "Module options = 0x%x.Setting LRM MODE\n",
2567                          options[0]);
2568
2569                 /* Changing to LRM mode takes quite few seconds.
2570                 So do it only if current mode is limiting
2571                 ( default is LRM )*/
2572                 if (cur_limiting_mode != SFP_LIMITING_MODE_VALUE)
2573                         return 0;
2574
2575                 bnx2x_cl45_write(bp, port,
2576                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2577                                ext_phy_addr,
2578                                MDIO_PMA_DEVAD,
2579                                MDIO_PMA_REG_LRM_MODE,
2580                                0);
2581                 bnx2x_cl45_write(bp, port,
2582                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2583                                ext_phy_addr,
2584                                MDIO_PMA_DEVAD,
2585                                MDIO_PMA_REG_ROM_VER2,
2586                                0x128);
2587                 bnx2x_cl45_write(bp, port,
2588                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2589                                ext_phy_addr,
2590                                MDIO_PMA_DEVAD,
2591                                MDIO_PMA_REG_MISC_CTRL0,
2592                                0x4008);
2593                 bnx2x_cl45_write(bp, port,
2594                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2595                                ext_phy_addr,
2596                                MDIO_PMA_DEVAD,
2597                                MDIO_PMA_REG_LRM_MODE,
2598                                0xaaaa);
2599         }
2600         return 0;
2601 }
2602
2603 static u8 bnx2x_wait_for_sfp_module_initialized(struct link_params *params)
2604 {
2605         u8 val;
2606         struct bnx2x *bp = params->bp;
2607         u16 timeout;
2608         /* Initialization time after hot-plug may take up to 300ms for some
2609         phys type ( e.g. JDSU ) */
2610         for (timeout = 0; timeout < 60; timeout++) {
2611                 if (bnx2x_read_sfp_module_eeprom(params, 1, 1, &val)
2612                     == 0) {
2613                         DP(NETIF_MSG_LINK, "SFP+ module initialization "
2614                                      "took %d ms\n", timeout * 5);
2615                         return 0;
2616                 }
2617                 msleep(5);
2618         }
2619         return -EINVAL;
2620 }
2621
2622 static u8 bnx2x_sfp_module_detection(struct link_params *params)
2623 {
2624         struct bnx2x *bp = params->bp;
2625         u8 module_type;
2626         u8 ext_phy_addr = ((params->ext_phy_config &
2627                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2628                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2629         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2630
2631         if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
2632                 DP(NETIF_MSG_LINK, "Module detection is not required "
2633                             "for this phy\n");
2634                 return 0;
2635         }
2636
2637         DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
2638                  params->port);
2639
2640         if (bnx2x_get_sfp_module_type(params,
2641                                     &module_type) != 0) {
2642                 DP(NETIF_MSG_LINK, "Failed to get valid module type\n");
2643                 if (!(params->feature_config_flags &
2644                       FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED)) {
2645                         /* In case module detection is disabled, it trys to
2646                         link up. The issue that can happen here is LRM /
2647                         LIMITING mode which set according to the module-type*/
2648                         DP(NETIF_MSG_LINK, "Unable to read module-type."
2649                                     "Probably due to Bit Stretching."
2650                                     " Proceeding...\n");
2651                 } else {
2652                         return -EINVAL;
2653                 }
2654         } else if (bnx2x_verify_sfp_module(params, module_type) !=
2655                    0) {
2656                 /* check SFP+ module compatibility */
2657                 DP(NETIF_MSG_LINK, "Module verification failed!!\n");
2658                 /* Turn on fault module-detected led */
2659                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
2660                                   MISC_REGISTERS_GPIO_HIGH,
2661                                   params->port);
2662                 return -EINVAL;
2663         }
2664
2665         /* Turn off fault module-detected led */
2666         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
2667                           MISC_REGISTERS_GPIO_LOW,
2668                           params->port);
2669
2670         /* Check and set limiting mode / LRM mode */
2671         if (bnx2x_bcm8726_set_limiting_mode(params, module_type)
2672              != 0) {
2673                 DP(NETIF_MSG_LINK, "Setting limiting mode failed!!\n");
2674                 return -EINVAL;
2675         }
2676
2677         /* Enable transmit for this module */
2678         bnx2x_bcm8726_set_transmitter(bp, params->port,
2679                                     ext_phy_addr, 1);
2680         return 0;
2681 }
2682
2683 void bnx2x_handle_module_detect_int(struct link_params *params)
2684 {
2685         struct bnx2x *bp = params->bp;
2686         u32 gpio_val;
2687         u8 port = params->port;
2688         /* Set valid module led off */
2689         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
2690                           MISC_REGISTERS_GPIO_HIGH,
2691                           params->port);
2692
2693         /* Get current gpio val refelecting module plugged in / out*/
2694         gpio_val = bnx2x_get_gpio(bp,  MISC_REGISTERS_GPIO_3, port);
2695
2696         /* Call the handling function in case module is detected */
2697         if (gpio_val == 0) {
2698
2699                 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
2700                                       MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
2701                                       port);
2702
2703                 if (bnx2x_wait_for_sfp_module_initialized(params)
2704                     == 0)
2705                         bnx2x_sfp_module_detection(params);
2706                 else
2707                         DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
2708         } else {
2709                 u8 ext_phy_addr = ((params->ext_phy_config &
2710                                     PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2711                                    PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2712                 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
2713                                       MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
2714                                       port);
2715                 /* Module was plugged out. */
2716                 /* Disable transmit for this module */
2717                 bnx2x_bcm8726_set_transmitter(bp, params->port,
2718                                             ext_phy_addr, 0);
2719         }
2720 }
2721
2722 static void bnx2x_bcm807x_force_10G(struct link_params *params)
2723 {
2724         struct bnx2x *bp = params->bp;
2725         u8 port = params->port;
2726         u8 ext_phy_addr = ((params->ext_phy_config &
2727                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2728                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2729         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2730
2731         /* Force KR or KX */
2732         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2733                        MDIO_PMA_DEVAD,
2734                        MDIO_PMA_REG_CTRL,
2735                        0x2040);
2736         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2737                        MDIO_PMA_DEVAD,
2738                        MDIO_PMA_REG_10G_CTRL2,
2739                        0x000b);
2740         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2741                        MDIO_PMA_DEVAD,
2742                        MDIO_PMA_REG_BCM_CTRL,
2743                        0x0000);
2744         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2745                        MDIO_AN_DEVAD,
2746                        MDIO_AN_REG_CTRL,
2747                        0x0000);
2748 }
2749 static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params)
2750 {
2751         struct bnx2x *bp = params->bp;
2752         u8 port = params->port;
2753         u16 val;
2754         u8 ext_phy_addr = ((params->ext_phy_config &
2755                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2756                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2757         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2758
2759         bnx2x_cl45_read(bp, params->port,
2760                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2761                       ext_phy_addr,
2762                       MDIO_PMA_DEVAD,
2763                       MDIO_PMA_REG_8073_CHIP_REV, &val);
2764
2765         if (val == 0) {
2766                 /* Mustn't set low power mode in 8073 A0 */
2767                 return;
2768         }
2769
2770         /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
2771         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2772                        MDIO_XS_DEVAD,
2773                        MDIO_XS_PLL_SEQUENCER, &val);
2774         val &= ~(1<<13);
2775         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2776                        MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2777
2778         /* PLL controls */
2779         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2780                        MDIO_XS_DEVAD, 0x805E, 0x1077);
2781         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2782                        MDIO_XS_DEVAD, 0x805D, 0x0000);
2783         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2784                        MDIO_XS_DEVAD, 0x805C, 0x030B);
2785         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2786                        MDIO_XS_DEVAD, 0x805B, 0x1240);
2787         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2788                        MDIO_XS_DEVAD, 0x805A, 0x2490);
2789
2790         /* Tx Controls */
2791         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2792                        MDIO_XS_DEVAD, 0x80A7, 0x0C74);
2793         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2794                        MDIO_XS_DEVAD, 0x80A6, 0x9041);
2795         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2796                        MDIO_XS_DEVAD, 0x80A5, 0x4640);
2797
2798         /* Rx Controls */
2799         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2800                        MDIO_XS_DEVAD, 0x80FE, 0x01C4);
2801         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2802                        MDIO_XS_DEVAD, 0x80FD, 0x9249);
2803         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2804                        MDIO_XS_DEVAD, 0x80FC, 0x2015);
2805
2806         /* Enable PLL sequencer  (use read-modify-write to set bit 13) */
2807         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2808                        MDIO_XS_DEVAD,
2809                        MDIO_XS_PLL_SEQUENCER, &val);
2810         val |= (1<<13);
2811         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2812                        MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2813 }
2814
2815 static void bnx2x_8073_set_pause_cl37(struct link_params *params,
2816                                   struct link_vars *vars)
2817 {
2818
2819         struct bnx2x *bp = params->bp;
2820         u16 cl37_val;
2821         u8 ext_phy_addr = ((params->ext_phy_config &
2822                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2823                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2824         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2825
2826         bnx2x_cl45_read(bp, params->port,
2827                       ext_phy_type,
2828                       ext_phy_addr,
2829                       MDIO_AN_DEVAD,
2830                       MDIO_AN_REG_CL37_FC_LD, &cl37_val);
2831
2832         cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2833         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2834
2835         if ((vars->ieee_fc &
2836             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
2837             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
2838                 cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
2839         }
2840         if ((vars->ieee_fc &
2841             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
2842             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
2843                 cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
2844         }
2845         if ((vars->ieee_fc &
2846             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
2847             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
2848                 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2849         }
2850         DP(NETIF_MSG_LINK,
2851                  "Ext phy AN advertize cl37 0x%x\n", cl37_val);
2852
2853         bnx2x_cl45_write(bp, params->port,
2854                        ext_phy_type,
2855                        ext_phy_addr,
2856                        MDIO_AN_DEVAD,
2857                        MDIO_AN_REG_CL37_FC_LD, cl37_val);
2858         msleep(500);
2859 }
2860
2861 static void bnx2x_ext_phy_set_pause(struct link_params *params,
2862                                   struct link_vars *vars)
2863 {
2864         struct bnx2x *bp = params->bp;
2865         u16 val;
2866         u8 ext_phy_addr = ((params->ext_phy_config &
2867                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2868                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2869         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2870
2871         /* read modify write pause advertizing */
2872         bnx2x_cl45_read(bp, params->port,
2873                       ext_phy_type,
2874                       ext_phy_addr,
2875                       MDIO_AN_DEVAD,
2876                       MDIO_AN_REG_ADV_PAUSE, &val);
2877
2878         val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
2879
2880         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2881
2882         if ((vars->ieee_fc &
2883             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
2884             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
2885                 val |=  MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
2886         }
2887         if ((vars->ieee_fc &
2888             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
2889             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
2890                 val |=
2891                  MDIO_AN_REG_ADV_PAUSE_PAUSE;
2892         }
2893         DP(NETIF_MSG_LINK,
2894                  "Ext phy AN advertize 0x%x\n", val);
2895         bnx2x_cl45_write(bp, params->port,
2896                        ext_phy_type,
2897                        ext_phy_addr,
2898                        MDIO_AN_DEVAD,
2899                        MDIO_AN_REG_ADV_PAUSE, val);
2900 }
2901 static void bnx2x_set_preemphasis(struct link_params *params)
2902 {
2903         u16 bank, i = 0;
2904         struct bnx2x *bp = params->bp;
2905
2906         for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
2907               bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) {
2908                         CL45_WR_OVER_CL22(bp, params->port,
2909                                               params->phy_addr,
2910                                               bank,
2911                                               MDIO_RX0_RX_EQ_BOOST,
2912                                               params->xgxs_config_rx[i]);
2913         }
2914
2915         for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
2916                       bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
2917                         CL45_WR_OVER_CL22(bp, params->port,
2918                                               params->phy_addr,
2919                                               bank,
2920                                               MDIO_TX0_TX_DRIVER,
2921                                               params->xgxs_config_tx[i]);
2922         }
2923 }
2924
2925 static void bnx2x_init_internal_phy(struct link_params *params,
2926                                 struct link_vars *vars)
2927 {
2928         struct bnx2x *bp = params->bp;
2929         if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
2930                 if ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
2931                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
2932                     (params->feature_config_flags &
2933                      FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
2934                         bnx2x_set_preemphasis(params);
2935
2936                 /* forced speed requested? */
2937                 if (vars->line_speed != SPEED_AUTO_NEG) {
2938                         DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
2939
2940                         /* disable autoneg */
2941                         bnx2x_set_autoneg(params, vars);
2942
2943                         /* program speed and duplex */
2944                         bnx2x_program_serdes(params, vars);
2945
2946                 } else { /* AN_mode */
2947                         DP(NETIF_MSG_LINK, "not SGMII, AN\n");
2948
2949                         /* AN enabled */
2950                         bnx2x_set_brcm_cl37_advertisment(params);
2951
2952                         /* program duplex & pause advertisement (for aneg) */
2953                         bnx2x_set_ieee_aneg_advertisment(params,
2954                                                        vars->ieee_fc);
2955
2956                         /* enable autoneg */
2957                         bnx2x_set_autoneg(params, vars);
2958
2959                         /* enable and restart AN */
2960                         bnx2x_restart_autoneg(params);
2961                 }
2962
2963         } else { /* SGMII mode */
2964                 DP(NETIF_MSG_LINK, "SGMII\n");
2965
2966                 bnx2x_initialize_sgmii_process(params, vars);
2967         }
2968 }
2969
2970 static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
2971 {
2972         struct bnx2x *bp = params->bp;
2973         u32 ext_phy_type;
2974         u8 ext_phy_addr;
2975         u16 cnt;
2976         u16 ctrl = 0;
2977         u16 val = 0;
2978         u8 rc = 0;
2979         if (vars->phy_flags & PHY_XGXS_FLAG) {
2980                 ext_phy_addr = ((params->ext_phy_config &
2981                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2982                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2983
2984                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2985                 /* Make sure that the soft reset is off (expect for the 8072:
2986                  * due to the lock, it will be done inside the specific
2987                  * handling)
2988                  */
2989                 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
2990                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
2991                    (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) &&
2992                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
2993                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
2994                         /* Wait for soft reset to get cleared upto 1 sec */
2995                         for (cnt = 0; cnt < 1000; cnt++) {
2996                                 bnx2x_cl45_read(bp, params->port,
2997                                               ext_phy_type,
2998                                               ext_phy_addr,
2999                                               MDIO_PMA_DEVAD,
3000                                               MDIO_PMA_REG_CTRL, &ctrl);
3001                                 if (!(ctrl & (1<<15)))
3002                                         break;
3003                                 msleep(1);
3004                         }
3005                         DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n",
3006                                  ctrl, cnt);
3007                 }
3008
3009                 switch (ext_phy_type) {
3010                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
3011                         break;
3012
3013                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
3014                         DP(NETIF_MSG_LINK, "XGXS 8705\n");
3015
3016                         bnx2x_cl45_write(bp, params->port,
3017                                        ext_phy_type,
3018                                        ext_phy_addr,
3019                                        MDIO_PMA_DEVAD,
3020                                        MDIO_PMA_REG_MISC_CTRL,
3021                                        0x8288);
3022                         bnx2x_cl45_write(bp, params->port,
3023                                        ext_phy_type,
3024                                        ext_phy_addr,
3025                                        MDIO_PMA_DEVAD,
3026                                        MDIO_PMA_REG_PHY_IDENTIFIER,
3027                                        0x7fbf);
3028                         bnx2x_cl45_write(bp, params->port,
3029                                        ext_phy_type,
3030                                        ext_phy_addr,
3031                                        MDIO_PMA_DEVAD,
3032                                        MDIO_PMA_REG_CMU_PLL_BYPASS,
3033                                        0x0100);
3034                         bnx2x_cl45_write(bp, params->port,
3035                                        ext_phy_type,
3036                                        ext_phy_addr,
3037                                        MDIO_WIS_DEVAD,
3038                                        MDIO_WIS_REG_LASI_CNTL, 0x1);
3039
3040                         bnx2x_save_bcm_spirom_ver(bp, params->port,
3041                                                 ext_phy_type,
3042                                                 ext_phy_addr,
3043                                                 params->shmem_base);
3044                         break;
3045
3046                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3047                         /* Wait until fw is loaded */
3048                         for (cnt = 0; cnt < 100; cnt++) {
3049                                 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3050                                               ext_phy_addr, MDIO_PMA_DEVAD,
3051                                               MDIO_PMA_REG_ROM_VER1, &val);
3052                                 if (val)
3053                                         break;
3054                                 msleep(10);
3055                         }
3056                         DP(NETIF_MSG_LINK, "XGXS 8706 is initialized "
3057                                 "after %d ms\n", cnt);
3058                         if ((params->feature_config_flags &
3059                              FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
3060                                 u8 i;
3061                                 u16 reg;
3062                                 for (i = 0; i < 4; i++) {
3063                                         reg = MDIO_XS_8706_REG_BANK_RX0 +
3064                                                 i*(MDIO_XS_8706_REG_BANK_RX1 -
3065                                                    MDIO_XS_8706_REG_BANK_RX0);
3066                                         bnx2x_cl45_read(bp, params->port,
3067                                                       ext_phy_type,
3068                                                       ext_phy_addr,
3069                                                       MDIO_XS_DEVAD,
3070                                                       reg, &val);
3071                                         /* Clear first 3 bits of the control */
3072                                         val &= ~0x7;
3073                                         /* Set control bits according to
3074                                         configuation */
3075                                         val |= (params->xgxs_config_rx[i] &
3076                                                 0x7);
3077                                         DP(NETIF_MSG_LINK, "Setting RX"
3078                                                  "Equalizer to BCM8706 reg 0x%x"
3079                                                  " <-- val 0x%x\n", reg, val);
3080                                         bnx2x_cl45_write(bp, params->port,
3081                                                        ext_phy_type,
3082                                                        ext_phy_addr,
3083                                                        MDIO_XS_DEVAD,
3084                                                        reg, val);
3085                                 }
3086                         }
3087                         /* Force speed */
3088                         /* First enable LASI */
3089                         bnx2x_cl45_write(bp, params->port,
3090                                        ext_phy_type,
3091                                        ext_phy_addr,
3092                                        MDIO_PMA_DEVAD,
3093                                        MDIO_PMA_REG_RX_ALARM_CTRL,
3094                                        0x0400);
3095                         bnx2x_cl45_write(bp, params->port,
3096                                        ext_phy_type,
3097                                        ext_phy_addr,
3098                                        MDIO_PMA_DEVAD,
3099                                        MDIO_PMA_REG_LASI_CTRL, 0x0004);
3100
3101                         if (params->req_line_speed == SPEED_10000) {
3102                                 DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
3103
3104                                 bnx2x_cl45_write(bp, params->port,
3105                                                ext_phy_type,
3106                                                ext_phy_addr,
3107                                                MDIO_PMA_DEVAD,
3108                                                MDIO_PMA_REG_DIGITAL_CTRL,
3109                                                0x400);
3110                         } else {
3111                                 /* Force 1Gbps using autoneg with 1G
3112                                 advertisment */
3113
3114                                 /* Allow CL37 through CL73 */
3115                                 DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
3116                                 bnx2x_cl45_write(bp, params->port,
3117                                                ext_phy_type,
3118                                                ext_phy_addr,
3119                                                MDIO_AN_DEVAD,
3120                                                MDIO_AN_REG_CL37_CL73,
3121                                                0x040c);
3122
3123                                 /* Enable Full-Duplex advertisment on CL37 */
3124                                 bnx2x_cl45_write(bp, params->port,
3125                                                ext_phy_type,
3126                                                ext_phy_addr,
3127                                                MDIO_AN_DEVAD,
3128                                                MDIO_AN_REG_CL37_FC_LP,
3129                                                0x0020);
3130                                 /* Enable CL37 AN */
3131                                 bnx2x_cl45_write(bp, params->port,
3132                                                ext_phy_type,
3133                                                ext_phy_addr,
3134                                                MDIO_AN_DEVAD,
3135                                                MDIO_AN_REG_CL37_AN,
3136                                                0x1000);
3137                                 /* 1G support */
3138                                 bnx2x_cl45_write(bp, params->port,
3139                                                ext_phy_type,
3140                                                ext_phy_addr,
3141                                                MDIO_AN_DEVAD,
3142                                                MDIO_AN_REG_ADV, (1<<5));
3143
3144                                 /* Enable clause 73 AN */
3145                                 bnx2x_cl45_write(bp, params->port,
3146                                                ext_phy_type,
3147                                                ext_phy_addr,
3148                                                MDIO_AN_DEVAD,
3149                                                MDIO_AN_REG_CTRL,
3150                                                0x1200);
3151
3152                         }
3153                         bnx2x_save_bcm_spirom_ver(bp, params->port,
3154                                                 ext_phy_type,
3155                                                 ext_phy_addr,
3156                                                 params->shmem_base);
3157                         break;
3158                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
3159                         DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
3160                         bnx2x_bcm8726_external_rom_boot(params);
3161
3162                         /* Need to call module detected on initialization since
3163                         the module detection triggered by actual module
3164                         insertion might occur before driver is loaded, and when
3165                         driver is loaded, it reset all registers, including the
3166                         transmitter */
3167                         bnx2x_sfp_module_detection(params);
3168                         if (params->req_line_speed == SPEED_1000) {
3169                                 DP(NETIF_MSG_LINK, "Setting 1G force\n");
3170                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3171                                                ext_phy_addr, MDIO_PMA_DEVAD,
3172                                                MDIO_PMA_REG_CTRL, 0x40);
3173                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3174                                                ext_phy_addr, MDIO_PMA_DEVAD,
3175                                                MDIO_PMA_REG_10G_CTRL2, 0xD);
3176                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3177                                                ext_phy_addr, MDIO_PMA_DEVAD,
3178                                                MDIO_PMA_REG_LASI_CTRL, 0x5);
3179                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3180                                                ext_phy_addr, MDIO_PMA_DEVAD,
3181                                                MDIO_PMA_REG_RX_ALARM_CTRL,
3182                                                0x400);
3183                         } else if ((params->req_line_speed ==
3184                                     SPEED_AUTO_NEG) &&
3185                                    ((params->speed_cap_mask &
3186                                      PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) {
3187                                 DP(NETIF_MSG_LINK, "Setting 1G clause37 \n");
3188                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3189                                                ext_phy_addr, MDIO_AN_DEVAD,
3190                                                MDIO_AN_REG_ADV, 0x20);
3191                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3192                                                ext_phy_addr, MDIO_AN_DEVAD,
3193                                                MDIO_AN_REG_CL37_CL73, 0x040c);
3194                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3195                                                ext_phy_addr, MDIO_AN_DEVAD,
3196                                                MDIO_AN_REG_CL37_FC_LD, 0x0020);
3197                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3198                                                ext_phy_addr, MDIO_AN_DEVAD,
3199                                                MDIO_AN_REG_CL37_AN, 0x1000);
3200                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3201                                                ext_phy_addr, MDIO_AN_DEVAD,
3202                                                MDIO_AN_REG_CTRL, 0x1200);
3203
3204                                 /* Enable RX-ALARM control to receive
3205                                 interrupt for 1G speed change */
3206                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3207                                                ext_phy_addr, MDIO_PMA_DEVAD,
3208                                                MDIO_PMA_REG_LASI_CTRL, 0x4);
3209                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3210                                                ext_phy_addr, MDIO_PMA_DEVAD,
3211                                                MDIO_PMA_REG_RX_ALARM_CTRL,
3212                                                0x400);
3213
3214                         } else { /* Default 10G. Set only LASI control */
3215                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3216                                                ext_phy_addr, MDIO_PMA_DEVAD,
3217                                                MDIO_PMA_REG_LASI_CTRL, 1);
3218                         }
3219
3220                         /* Set TX PreEmphasis if needed */
3221                         if ((params->feature_config_flags &
3222                              FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
3223                                 DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
3224                                          "TX_CTRL2 0x%x\n",
3225                                          params->xgxs_config_tx[0],
3226                                          params->xgxs_config_tx[1]);
3227                                 bnx2x_cl45_write(bp, params->port,
3228                                                ext_phy_type,
3229                                                ext_phy_addr,
3230                                                MDIO_PMA_DEVAD,
3231                                                MDIO_PMA_REG_8726_TX_CTRL1,
3232                                                params->xgxs_config_tx[0]);
3233
3234                                 bnx2x_cl45_write(bp, params->port,
3235                                                ext_phy_type,
3236                                                ext_phy_addr,
3237                                                MDIO_PMA_DEVAD,
3238                                                MDIO_PMA_REG_8726_TX_CTRL2,
3239                                                params->xgxs_config_tx[1]);
3240                         }
3241                         break;
3242                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3243                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
3244                 {
3245                         u16 tmp1;
3246                         u16 rx_alarm_ctrl_val;
3247                         u16 lasi_ctrl_val;
3248                         if (ext_phy_type ==
3249                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
3250                                 rx_alarm_ctrl_val = 0x400;
3251                                 lasi_ctrl_val = 0x0004;
3252                         } else {
3253                                 rx_alarm_ctrl_val = (1<<2);
3254                                 lasi_ctrl_val = 0x0004;
3255                         }
3256
3257                         /* enable LASI */
3258                         bnx2x_cl45_write(bp, params->port,
3259                                    ext_phy_type,
3260                                    ext_phy_addr,
3261                                    MDIO_PMA_DEVAD,
3262                                    MDIO_PMA_REG_RX_ALARM_CTRL,
3263                                    rx_alarm_ctrl_val);
3264
3265                         bnx2x_cl45_write(bp, params->port,
3266                                        ext_phy_type,
3267                                        ext_phy_addr,
3268                                        MDIO_PMA_DEVAD,
3269                                        MDIO_PMA_REG_LASI_CTRL,
3270                                        lasi_ctrl_val);
3271
3272                         bnx2x_8073_set_pause_cl37(params, vars);
3273
3274                         if (ext_phy_type ==
3275                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072){
3276                                 bnx2x_bcm8072_external_rom_boot(params);
3277                         } else {
3278
3279                                 /* In case of 8073 with long xaui lines,
3280                                 don't set the 8073 xaui low power*/
3281                                 bnx2x_bcm8073_set_xaui_low_power_mode(params);
3282                         }
3283
3284                         bnx2x_cl45_read(bp, params->port,
3285                                       ext_phy_type,
3286                                       ext_phy_addr,
3287                                       MDIO_PMA_DEVAD,
3288                                       MDIO_PMA_REG_M8051_MSGOUT_REG,
3289                                       &tmp1);
3290
3291                         bnx2x_cl45_read(bp, params->port,
3292                                       ext_phy_type,
3293                                       ext_phy_addr,
3294                                       MDIO_PMA_DEVAD,
3295                                       MDIO_PMA_REG_RX_ALARM, &tmp1);
3296
3297                         DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1):"
3298                                              "0x%x\n", tmp1);
3299
3300                         /* If this is forced speed, set to KR or KX
3301                          * (all other are not supported)
3302                          */
3303                         if (params->loopback_mode == LOOPBACK_EXT) {
3304                                 bnx2x_bcm807x_force_10G(params);
3305                                 DP(NETIF_MSG_LINK,
3306                                         "Forced speed 10G on 807X\n");
3307                                 break;
3308                         } else {
3309                                 bnx2x_cl45_write(bp, params->port,
3310                                                ext_phy_type, ext_phy_addr,
3311                                                MDIO_PMA_DEVAD,
3312                                                MDIO_PMA_REG_BCM_CTRL,
3313                                                0x0002);
3314                         }
3315                         if (params->req_line_speed != SPEED_AUTO_NEG) {
3316                                 if (params->req_line_speed == SPEED_10000) {
3317                                         val = (1<<7);
3318                                 } else if (params->req_line_speed ==
3319                                            SPEED_2500) {
3320                                         val = (1<<5);
3321                                         /* Note that 2.5G works only
3322                                         when used with 1G advertisment */
3323                                 } else
3324                                         val = (1<<5);
3325                         } else {
3326
3327                                 val = 0;
3328                                 if (params->speed_cap_mask &
3329                                         PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
3330                                         val |= (1<<7);
3331
3332                                 /* Note that 2.5G works only when
3333                                 used with 1G advertisment */
3334                                 if (params->speed_cap_mask &
3335                                         (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
3336                                          PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
3337                                         val |= (1<<5);
3338                                 DP(NETIF_MSG_LINK,
3339                                          "807x autoneg val = 0x%x\n", val);
3340                         }
3341
3342                         bnx2x_cl45_write(bp, params->port,
3343                                        ext_phy_type,
3344                                        ext_phy_addr,
3345                                        MDIO_AN_DEVAD,
3346                                        MDIO_AN_REG_ADV, val);
3347
3348                         if (ext_phy_type ==
3349                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3350
3351                                 bnx2x_cl45_read(bp, params->port,
3352                                               ext_phy_type,
3353                                               ext_phy_addr,
3354                                               MDIO_AN_DEVAD,
3355                                               MDIO_AN_REG_8073_2_5G, &tmp1);
3356
3357                                 if (((params->speed_cap_mask &
3358                                       PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
3359                                      (params->req_line_speed ==
3360                                       SPEED_AUTO_NEG)) ||
3361                                     (params->req_line_speed ==
3362                                      SPEED_2500)) {
3363                                         u16 phy_ver;
3364                                         /* Allow 2.5G for A1 and above */
3365                                         bnx2x_cl45_read(bp, params->port,
3366                                          PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
3367                                          ext_phy_addr,
3368                                          MDIO_PMA_DEVAD,
3369                                          MDIO_PMA_REG_8073_CHIP_REV, &phy_ver);
3370                                         DP(NETIF_MSG_LINK, "Add 2.5G\n");
3371                                         if (phy_ver > 0)
3372                                                 tmp1 |= 1;
3373                                         else
3374                                                 tmp1 &= 0xfffe;
3375                                 } else {
3376                                         DP(NETIF_MSG_LINK, "Disable 2.5G\n");
3377                                         tmp1 &= 0xfffe;
3378                                 }
3379
3380                                 bnx2x_cl45_write(bp, params->port,
3381                                                ext_phy_type,
3382                                                ext_phy_addr,
3383                                                MDIO_AN_DEVAD,
3384                                                MDIO_AN_REG_8073_2_5G, tmp1);
3385                         }
3386
3387                         /* Add support for CL37 (passive mode) II */
3388
3389                         bnx2x_cl45_read(bp, params->port,
3390                                        ext_phy_type,
3391                                        ext_phy_addr,
3392                                        MDIO_AN_DEVAD,
3393                                        MDIO_AN_REG_CL37_FC_LD,
3394                                        &tmp1);
3395
3396                         bnx2x_cl45_write(bp, params->port,
3397                                        ext_phy_type,
3398                                        ext_phy_addr,
3399                                        MDIO_AN_DEVAD,
3400                                        MDIO_AN_REG_CL37_FC_LD, (tmp1 |
3401                                        ((params->req_duplex == DUPLEX_FULL) ?
3402                                        0x20 : 0x40)));
3403
3404                         /* Add support for CL37 (passive mode) III */
3405                         bnx2x_cl45_write(bp, params->port,
3406                                        ext_phy_type,
3407                                        ext_phy_addr,
3408                                        MDIO_AN_DEVAD,
3409                                        MDIO_AN_REG_CL37_AN, 0x1000);
3410
3411                         if (ext_phy_type ==
3412                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3413                                 /* The SNR will improve about 2db by changing
3414                                 BW and FEE main tap. Rest commands are executed
3415                                 after link is up*/
3416                                 /*Change FFE main cursor to 5 in EDC register*/
3417                                 if (bnx2x_8073_is_snr_needed(params))
3418                                         bnx2x_cl45_write(bp, params->port,
3419                                                     ext_phy_type,
3420                                                     ext_phy_addr,
3421                                                     MDIO_PMA_DEVAD,
3422                                                     MDIO_PMA_REG_EDC_FFE_MAIN,
3423                                                     0xFB0C);
3424
3425                                 /* Enable FEC (Forware Error Correction)
3426                                 Request in the AN */
3427                                 bnx2x_cl45_read(bp, params->port,
3428                                               ext_phy_type,
3429                                               ext_phy_addr,
3430                                               MDIO_AN_DEVAD,
3431                                               MDIO_AN_REG_ADV2, &tmp1);
3432
3433                                 tmp1 |= (1<<15);
3434
3435                                 bnx2x_cl45_write(bp, params->port,
3436                                                ext_phy_type,
3437                                                ext_phy_addr,
3438                                                MDIO_AN_DEVAD,
3439                                                MDIO_AN_REG_ADV2, tmp1);
3440
3441                         }
3442
3443                         bnx2x_ext_phy_set_pause(params, vars);
3444
3445                         /* Restart autoneg */
3446                         msleep(500);
3447                         bnx2x_cl45_write(bp, params->port,
3448                                        ext_phy_type,
3449                                        ext_phy_addr,
3450                                        MDIO_AN_DEVAD,
3451                                        MDIO_AN_REG_CTRL, 0x1200);
3452                         DP(NETIF_MSG_LINK, "807x Autoneg Restart: "
3453                            "Advertise 1G=%x, 10G=%x\n",
3454                            ((val & (1<<5)) > 0),
3455                            ((val & (1<<7)) > 0));
3456                         break;
3457                 }
3458                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3459                 {
3460                         u16 fw_ver1, fw_ver2;
3461                         DP(NETIF_MSG_LINK,
3462                                 "Setting the SFX7101 LASI indication\n");
3463
3464                         bnx2x_cl45_write(bp, params->port,
3465                                        ext_phy_type,
3466                                        ext_phy_addr,
3467                                        MDIO_PMA_DEVAD,
3468                                        MDIO_PMA_REG_LASI_CTRL, 0x1);
3469                         DP(NETIF_MSG_LINK,
3470                           "Setting the SFX7101 LED to blink on traffic\n");
3471                         bnx2x_cl45_write(bp, params->port,
3472                                        ext_phy_type,
3473                                        ext_phy_addr,
3474                                        MDIO_PMA_DEVAD,
3475                                        MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
3476
3477                         bnx2x_ext_phy_set_pause(params, vars);
3478                         /* Restart autoneg */
3479                         bnx2x_cl45_read(bp, params->port,
3480                                       ext_phy_type,
3481                                       ext_phy_addr,
3482                                       MDIO_AN_DEVAD,
3483                                       MDIO_AN_REG_CTRL, &val);
3484                         val |= 0x200;
3485                         bnx2x_cl45_write(bp, params->port,
3486                                        ext_phy_type,
3487                                        ext_phy_addr,
3488                                        MDIO_AN_DEVAD,
3489                                        MDIO_AN_REG_CTRL, val);
3490
3491                         /* Save spirom version */
3492                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3493                                       ext_phy_addr, MDIO_PMA_DEVAD,
3494                                       MDIO_PMA_REG_7101_VER1, &fw_ver1);
3495
3496                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3497                                       ext_phy_addr, MDIO_PMA_DEVAD,
3498                                       MDIO_PMA_REG_7101_VER2, &fw_ver2);
3499
3500                         bnx2x_save_spirom_version(params->bp, params->port,
3501                                                 params->shmem_base,
3502                                                 (u32)(fw_ver1<<16 | fw_ver2));
3503
3504                         break;
3505                 }
3506                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
3507                         DP(NETIF_MSG_LINK,
3508                                 "Setting the BCM8481 LASI control\n");
3509
3510                         bnx2x_cl45_write(bp, params->port,
3511                                        ext_phy_type,
3512                                        ext_phy_addr,
3513                                        MDIO_PMA_DEVAD,
3514                                        MDIO_PMA_REG_LASI_CTRL, 0x1);
3515
3516                         /* Restart autoneg */
3517                         bnx2x_cl45_read(bp, params->port,
3518                                       ext_phy_type,
3519                                       ext_phy_addr,
3520                                       MDIO_AN_DEVAD,
3521                                       MDIO_AN_REG_CTRL, &val);
3522                         val |= 0x200;
3523                         bnx2x_cl45_write(bp, params->port,
3524                                        ext_phy_type,
3525                                        ext_phy_addr,
3526                                        MDIO_AN_DEVAD,
3527                                        MDIO_AN_REG_CTRL, val);
3528
3529                         bnx2x_save_bcm_spirom_ver(bp, params->port,
3530                                                 ext_phy_type,
3531                                                 ext_phy_addr,
3532                                                 params->shmem_base);
3533
3534                         break;
3535                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
3536                         DP(NETIF_MSG_LINK,
3537                                  "XGXS PHY Failure detected 0x%x\n",
3538                                  params->ext_phy_config);
3539                         rc = -EINVAL;
3540                         break;
3541                 default:
3542                         DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
3543                                   params->ext_phy_config);
3544                         rc = -EINVAL;
3545                         break;
3546                 }
3547
3548         } else { /* SerDes */
3549
3550                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3551                 switch (ext_phy_type) {
3552                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
3553                         DP(NETIF_MSG_LINK, "SerDes Direct\n");
3554                         break;
3555
3556                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
3557                         DP(NETIF_MSG_LINK, "SerDes 5482\n");
3558                         break;
3559
3560                 default:
3561                         DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
3562                            params->ext_phy_config);
3563                         break;
3564                 }
3565         }
3566         return rc;
3567 }
3568
3569
3570 static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
3571                                  struct link_vars *vars)
3572 {
3573         struct bnx2x *bp = params->bp;
3574         u32 ext_phy_type;
3575         u8 ext_phy_addr;
3576         u16 val1 = 0, val2;
3577         u16 rx_sd, pcs_status;
3578         u8 ext_phy_link_up = 0;
3579         u8 port = params->port;
3580         if (vars->phy_flags & PHY_XGXS_FLAG) {
3581                 ext_phy_addr = ((params->ext_phy_config &
3582                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3583                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3584
3585                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3586                 switch (ext_phy_type) {
3587                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
3588                         DP(NETIF_MSG_LINK, "XGXS Direct\n");
3589                         ext_phy_link_up = 1;
3590                         break;
3591
3592                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
3593                         DP(NETIF_MSG_LINK, "XGXS 8705\n");
3594                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3595                                       ext_phy_addr,
3596                                       MDIO_WIS_DEVAD,
3597                                       MDIO_WIS_REG_LASI_STATUS, &val1);
3598                         DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
3599
3600                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3601                                       ext_phy_addr,
3602                                       MDIO_WIS_DEVAD,
3603                                       MDIO_WIS_REG_LASI_STATUS, &val1);
3604                         DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
3605
3606                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3607                                       ext_phy_addr,
3608                                       MDIO_PMA_DEVAD,
3609                                       MDIO_PMA_REG_RX_SD, &rx_sd);
3610                         DP(NETIF_MSG_LINK, "8705 rx_sd 0x%x\n", rx_sd);
3611                         ext_phy_link_up = (rx_sd & 0x1);
3612                         if (ext_phy_link_up)
3613                                 vars->line_speed = SPEED_10000;
3614                         break;
3615
3616                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3617                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
3618                         DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
3619                         /* Clear RX Alarm*/
3620                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3621                                       ext_phy_addr,
3622                                       MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM,
3623                                       &val2);
3624                         /* clear LASI indication*/
3625                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3626                                       ext_phy_addr,
3627                                       MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
3628                                       &val1);
3629                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3630                                       ext_phy_addr,
3631                                       MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
3632                                       &val2);
3633                         DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x-->"
3634                                      "0x%x\n", val1, val2);
3635
3636                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3637                                       ext_phy_addr,
3638                                       MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD,
3639                                       &rx_sd);
3640                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3641                                       ext_phy_addr,
3642                                       MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS,
3643                                       &pcs_status);
3644                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3645                                       ext_phy_addr,
3646                                       MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
3647                                       &val2);
3648                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3649                                       ext_phy_addr,
3650                                       MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
3651                                       &val2);
3652
3653                         DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x"
3654                            "  pcs_status 0x%x 1Gbps link_status 0x%x\n",
3655                            rx_sd, pcs_status, val2);
3656                         /* link is up if both bit 0 of pmd_rx_sd and
3657                          * bit 0 of pcs_status are set, or if the autoneg bit
3658                            1 is set
3659                          */
3660                         ext_phy_link_up = ((rx_sd & pcs_status & 0x1) ||
3661                                            (val2 & (1<<1)));
3662                         if (ext_phy_link_up) {
3663                                 if (ext_phy_type ==
3664                                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
3665                                         /* If transmitter is disabled,
3666                                         ignore false link up indication */
3667                                         bnx2x_cl45_read(bp, params->port,
3668                                                    ext_phy_type,
3669                                                    ext_phy_addr,
3670                                                    MDIO_PMA_DEVAD,
3671                                                    MDIO_PMA_REG_PHY_IDENTIFIER,
3672                                                    &val1);
3673                                         if (val1 & (1<<15)) {
3674                                                 DP(NETIF_MSG_LINK, "Tx is "
3675                                                             "disabled\n");
3676                                                 ext_phy_link_up = 0;
3677                                                 break;
3678                                         }
3679                                 }
3680
3681                                 if (val2 & (1<<1))
3682                                         vars->line_speed = SPEED_1000;
3683                                 else
3684                                         vars->line_speed = SPEED_10000;
3685                         }
3686
3687                         break;
3688                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3689                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
3690                 {
3691                         u16 link_status = 0;
3692                         u16 an1000_status = 0;
3693                         if (ext_phy_type ==
3694                              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
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, &val1);
3700                         bnx2x_cl45_read(bp, params->port,
3701                                       ext_phy_type,
3702                                       ext_phy_addr,
3703                                       MDIO_PCS_DEVAD,
3704                                       MDIO_PCS_REG_LASI_STATUS, &val2);
3705                         DP(NETIF_MSG_LINK,
3706                                  "870x LASI status 0x%x->0x%x\n",
3707                                   val1, val2);
3708
3709                         } else {
3710                                 /* In 8073, port1 is directed through emac0 and
3711                                  * port0 is directed through emac1
3712                                  */
3713                                 bnx2x_cl45_read(bp, params->port,
3714                                               ext_phy_type,
3715                                               ext_phy_addr,
3716                                               MDIO_PMA_DEVAD,
3717                                               MDIO_PMA_REG_LASI_STATUS, &val1);
3718
3719                                 DP(NETIF_MSG_LINK,
3720                                          "8703 LASI status 0x%x\n",
3721                                           val1);
3722                         }
3723
3724                         /* clear the interrupt LASI status register */
3725                         bnx2x_cl45_read(bp, params->port,
3726                                       ext_phy_type,
3727                                       ext_phy_addr,
3728                                       MDIO_PCS_DEVAD,
3729                                       MDIO_PCS_REG_STATUS, &val2);
3730                         bnx2x_cl45_read(bp, params->port,
3731                                       ext_phy_type,
3732                                       ext_phy_addr,
3733                                       MDIO_PCS_DEVAD,
3734                                       MDIO_PCS_REG_STATUS, &val1);
3735                         DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n",
3736                            val2, val1);
3737                         /* Clear MSG-OUT */
3738                         bnx2x_cl45_read(bp, params->port,
3739                                       ext_phy_type,
3740                                       ext_phy_addr,
3741                                       MDIO_PMA_DEVAD,
3742                                       MDIO_PMA_REG_M8051_MSGOUT_REG,
3743                                       &val1);
3744
3745                         /* Check the LASI */
3746                         bnx2x_cl45_read(bp, params->port,
3747                                       ext_phy_type,
3748                                       ext_phy_addr,
3749                                       MDIO_PMA_DEVAD,
3750                                       MDIO_PMA_REG_RX_ALARM, &val2);
3751
3752                         DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
3753
3754                         /* Check the link status */
3755                         bnx2x_cl45_read(bp, params->port,
3756                                       ext_phy_type,
3757                                       ext_phy_addr,
3758                                       MDIO_PCS_DEVAD,
3759                                       MDIO_PCS_REG_STATUS, &val2);
3760                         DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
3761
3762                         bnx2x_cl45_read(bp, params->port,
3763                                       ext_phy_type,
3764                                       ext_phy_addr,
3765                                       MDIO_PMA_DEVAD,
3766                                       MDIO_PMA_REG_STATUS, &val2);
3767                         bnx2x_cl45_read(bp, params->port,
3768                                       ext_phy_type,
3769                                       ext_phy_addr,
3770                                       MDIO_PMA_DEVAD,
3771                                       MDIO_PMA_REG_STATUS, &val1);
3772                         ext_phy_link_up = ((val1 & 4) == 4);
3773                         DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
3774                         if (ext_phy_type ==
3775                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3776
3777                                 if (ext_phy_link_up &&
3778                                     ((params->req_line_speed !=
3779                                         SPEED_10000))) {
3780                                         if (bnx2x_bcm8073_xaui_wa(params)
3781                                              != 0) {
3782                                                 ext_phy_link_up = 0;
3783                                                 break;
3784                                         }
3785                                 }
3786                                 bnx2x_cl45_read(bp, params->port,
3787                                               ext_phy_type,
3788                                               ext_phy_addr,
3789                                               MDIO_AN_DEVAD,
3790                                               MDIO_AN_REG_LINK_STATUS,
3791                                               &an1000_status);
3792                                 bnx2x_cl45_read(bp, params->port,
3793                                               ext_phy_type,
3794                                               ext_phy_addr,
3795                                               MDIO_AN_DEVAD,
3796                                               MDIO_AN_REG_LINK_STATUS,
3797                                               &an1000_status);
3798
3799                                 /* Check the link status on 1.1.2 */
3800                                 bnx2x_cl45_read(bp, params->port,
3801                                               ext_phy_type,
3802                                               ext_phy_addr,
3803                                               MDIO_PMA_DEVAD,
3804                                               MDIO_PMA_REG_STATUS, &val2);
3805                                 bnx2x_cl45_read(bp, params->port,
3806                                               ext_phy_type,
3807                                               ext_phy_addr,
3808                                               MDIO_PMA_DEVAD,
3809                                               MDIO_PMA_REG_STATUS, &val1);
3810                                 DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
3811                                              "an_link_status=0x%x\n",
3812                                           val2, val1, an1000_status);
3813
3814                                 ext_phy_link_up = (((val1 & 4) == 4) ||
3815                                                 (an1000_status & (1<<1)));
3816                                 if (ext_phy_link_up &&
3817                                     bnx2x_8073_is_snr_needed(params)) {
3818                                         /* The SNR will improve about 2dbby
3819                                         changing the BW and FEE main tap.*/
3820
3821                                         /* The 1st write to change FFE main
3822                                         tap is set before restart AN */
3823                                         /* Change PLL Bandwidth in EDC
3824                                         register */
3825                                         bnx2x_cl45_write(bp, port, ext_phy_type,
3826                                                     ext_phy_addr,
3827                                                     MDIO_PMA_DEVAD,
3828                                                     MDIO_PMA_REG_PLL_BANDWIDTH,
3829                                                     0x26BC);
3830
3831                                         /* Change CDR Bandwidth in EDC
3832                                         register */
3833                                         bnx2x_cl45_write(bp, port, ext_phy_type,
3834                                                     ext_phy_addr,
3835                                                     MDIO_PMA_DEVAD,
3836                                                     MDIO_PMA_REG_CDR_BANDWIDTH,
3837                                                     0x0333);
3838
3839
3840                                 }
3841                                 bnx2x_cl45_read(bp, params->port,
3842                                            ext_phy_type,
3843                                            ext_phy_addr,
3844                                            MDIO_PMA_DEVAD,
3845                                            MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
3846                                            &link_status);
3847
3848                                 /* Bits 0..2 --> speed detected,
3849                                    bits 13..15--> link is down */
3850                                 if ((link_status & (1<<2)) &&
3851                                     (!(link_status & (1<<15)))) {
3852                                         ext_phy_link_up = 1;
3853                                         vars->line_speed = SPEED_10000;
3854                                         DP(NETIF_MSG_LINK,
3855                                                  "port %x: External link"
3856                                                  " up in 10G\n", params->port);
3857                                 } else if ((link_status & (1<<1)) &&
3858                                            (!(link_status & (1<<14)))) {
3859                                         ext_phy_link_up = 1;
3860                                         vars->line_speed = SPEED_2500;
3861                                         DP(NETIF_MSG_LINK,
3862                                                  "port %x: External link"
3863                                                  " up in 2.5G\n", params->port);
3864                                 } else if ((link_status & (1<<0)) &&
3865                                            (!(link_status & (1<<13)))) {
3866                                         ext_phy_link_up = 1;
3867                                         vars->line_speed = SPEED_1000;
3868                                         DP(NETIF_MSG_LINK,
3869                                                  "port %x: External link"
3870                                                  " up in 1G\n", params->port);
3871                                 } else {
3872                                         ext_phy_link_up = 0;
3873                                         DP(NETIF_MSG_LINK,
3874                                                  "port %x: External link"
3875                                                  " is down\n", params->port);
3876                                 }
3877                         } else {
3878                                 /* See if 1G link is up for the 8072 */
3879                                 bnx2x_cl45_read(bp, params->port,
3880                                               ext_phy_type,
3881                                               ext_phy_addr,
3882                                               MDIO_AN_DEVAD,
3883                                               MDIO_AN_REG_LINK_STATUS,
3884                                               &an1000_status);
3885                                 bnx2x_cl45_read(bp, params->port,
3886                                               ext_phy_type,
3887                                               ext_phy_addr,
3888                                               MDIO_AN_DEVAD,
3889                                               MDIO_AN_REG_LINK_STATUS,
3890                                               &an1000_status);
3891                                 if (an1000_status & (1<<1)) {
3892                                         ext_phy_link_up = 1;
3893                                         vars->line_speed = SPEED_1000;
3894                                         DP(NETIF_MSG_LINK,
3895                                                  "port %x: External link"
3896                                                  " up in 1G\n", params->port);
3897                                 } else if (ext_phy_link_up) {
3898                                         ext_phy_link_up = 1;
3899                                         vars->line_speed = SPEED_10000;
3900                                         DP(NETIF_MSG_LINK,
3901                                                  "port %x: External link"
3902                                                  " up in 10G\n", params->port);
3903                                 }
3904                         }
3905
3906
3907                         break;
3908                 }
3909                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3910                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3911                                       ext_phy_addr,
3912                                       MDIO_PMA_DEVAD,
3913                                       MDIO_PMA_REG_LASI_STATUS, &val2);
3914                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3915                                       ext_phy_addr,
3916                                       MDIO_PMA_DEVAD,
3917                                       MDIO_PMA_REG_LASI_STATUS, &val1);
3918                         DP(NETIF_MSG_LINK,
3919                                  "10G-base-T LASI status 0x%x->0x%x\n",
3920                                   val2, val1);
3921                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3922                                       ext_phy_addr,
3923                                       MDIO_PMA_DEVAD,
3924                                       MDIO_PMA_REG_STATUS, &val2);
3925                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3926                                       ext_phy_addr,
3927                                       MDIO_PMA_DEVAD,
3928                                       MDIO_PMA_REG_STATUS, &val1);
3929                         DP(NETIF_MSG_LINK,
3930                                  "10G-base-T PMA status 0x%x->0x%x\n",
3931                                  val2, val1);
3932                         ext_phy_link_up = ((val1 & 4) == 4);
3933                         /* if link is up
3934                          * print the AN outcome of the SFX7101 PHY
3935                          */
3936                         if (ext_phy_link_up) {
3937                                 bnx2x_cl45_read(bp, params->port,
3938                                               ext_phy_type,
3939                                               ext_phy_addr,
3940                                               MDIO_AN_DEVAD,
3941                                               MDIO_AN_REG_MASTER_STATUS,
3942                                               &val2);
3943                                 vars->line_speed = SPEED_10000;
3944                                 DP(NETIF_MSG_LINK,
3945                                          "SFX7101 AN status 0x%x->Master=%x\n",
3946                                           val2,
3947                                          (val2 & (1<<14)));
3948                         }
3949                         break;
3950                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
3951                         /* Clear LASI interrupt */
3952                         bnx2x_cl45_read(bp, params->port,
3953                                       ext_phy_type,
3954                                       ext_phy_addr,
3955                                       MDIO_PMA_DEVAD,
3956                                       MDIO_PMA_REG_LASI_STATUS, &val1);
3957                         DP(NETIF_MSG_LINK, "8481 LASI status reg = 0x%x\n",
3958                                  val1);
3959
3960                         /* Check 10G-BaseT link status */
3961                         /* Check Global PMD signal ok */
3962                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3963                                       ext_phy_addr,
3964                                       MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD,
3965                                       &rx_sd);
3966                         /* Check PCS block lock */
3967                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3968                                       ext_phy_addr,
3969                                       MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS,
3970                                       &pcs_status);
3971                         DP(NETIF_MSG_LINK, "8481 1.a = 0x%x, 1.20 = 0x%x\n",
3972                                  rx_sd, pcs_status);
3973                         if (rx_sd & pcs_status & 0x1) {
3974                                 vars->line_speed = SPEED_10000;
3975                                 ext_phy_link_up = 1;
3976                         } else {
3977
3978                                 /* Check 1000-BaseT link status */
3979                                 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3980                                               ext_phy_addr,
3981                                               MDIO_AN_DEVAD, 0xFFE1,
3982                                               &val1);
3983
3984                                 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3985                                               ext_phy_addr,
3986                                               MDIO_AN_DEVAD, 0xFFE1,
3987                                               &val2);
3988                                 DP(NETIF_MSG_LINK, "8481 7.FFE1 ="
3989                                              "0x%x-->0x%x\n", val1, val2);
3990                                 if (val2 & (1<<2)) {
3991                                         vars->line_speed = SPEED_1000;
3992                                         ext_phy_link_up = 1;
3993                                 }
3994                         }
3995
3996                         break;
3997                 default:
3998                         DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
3999                            params->ext_phy_config);
4000                         ext_phy_link_up = 0;
4001                         break;
4002                 }
4003
4004         } else { /* SerDes */
4005                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
4006                 switch (ext_phy_type) {
4007                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
4008                         DP(NETIF_MSG_LINK, "SerDes Direct\n");
4009                         ext_phy_link_up = 1;
4010                         break;
4011
4012                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
4013                         DP(NETIF_MSG_LINK, "SerDes 5482\n");
4014                         ext_phy_link_up = 1;
4015                         break;
4016
4017                 default:
4018                         DP(NETIF_MSG_LINK,
4019                                  "BAD SerDes ext_phy_config 0x%x\n",
4020                                  params->ext_phy_config);
4021                         ext_phy_link_up = 0;
4022                         break;
4023                 }
4024         }
4025
4026         return ext_phy_link_up;
4027 }
4028
4029 static void bnx2x_link_int_enable(struct link_params *params)
4030 {
4031         u8 port = params->port;
4032         u32 ext_phy_type;
4033         u32 mask;
4034         struct bnx2x *bp = params->bp;
4035         /* setting the status to report on link up
4036            for either XGXS or SerDes */
4037
4038         if (params->switch_cfg == SWITCH_CFG_10G) {
4039                 mask = (NIG_MASK_XGXS0_LINK10G |
4040                         NIG_MASK_XGXS0_LINK_STATUS);
4041                 DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
4042                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4043                 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
4044                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
4045                     (ext_phy_type !=
4046                                 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) {
4047                         mask |= NIG_MASK_MI_INT;
4048                         DP(NETIF_MSG_LINK, "enabled external phy int\n");
4049                 }
4050
4051         } else { /* SerDes */
4052                 mask = NIG_MASK_SERDES0_LINK_STATUS;
4053                 DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
4054                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
4055                 if ((ext_phy_type !=
4056                                 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
4057                     (ext_phy_type !=
4058                                 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) {
4059                         mask |= NIG_MASK_MI_INT;
4060                         DP(NETIF_MSG_LINK, "enabled external phy int\n");
4061                 }
4062         }
4063         bnx2x_bits_en(bp,
4064                       NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
4065                       mask);
4066         DP(NETIF_MSG_LINK, "port %x, is_xgxs=%x, int_status 0x%x\n", port,
4067                  (params->switch_cfg == SWITCH_CFG_10G),
4068                  REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
4069
4070         DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
4071                  REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
4072                  REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
4073                  REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
4074         DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
4075            REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
4076            REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
4077 }
4078
4079
4080 /*
4081  * link management
4082  */
4083 static void bnx2x_link_int_ack(struct link_params *params,
4084                              struct link_vars *vars, u8 is_10g)
4085 {
4086         struct bnx2x *bp = params->bp;
4087         u8 port = params->port;
4088
4089         /* first reset all status
4090          * we assume only one line will be change at a time */
4091         bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4092                      (NIG_STATUS_XGXS0_LINK10G |
4093                       NIG_STATUS_XGXS0_LINK_STATUS |
4094                       NIG_STATUS_SERDES0_LINK_STATUS));
4095         if (vars->phy_link_up) {
4096                 if (is_10g) {
4097                         /* Disable the 10G link interrupt
4098                          * by writing 1 to the status register
4099                          */
4100                         DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
4101                         bnx2x_bits_en(bp,
4102                                       NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4103                                       NIG_STATUS_XGXS0_LINK10G);
4104
4105                 } else if (params->switch_cfg == SWITCH_CFG_10G) {
4106                         /* Disable the link interrupt
4107                          * by writing 1 to the relevant lane
4108                          * in the status register
4109                          */
4110                         u32 ser_lane = ((params->lane_config &
4111                                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
4112                                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
4113
4114                         DP(NETIF_MSG_LINK, "1G XGXS phy link up\n");
4115                         bnx2x_bits_en(bp,
4116                                       NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4117                                       ((1 << ser_lane) <<
4118                                        NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
4119
4120                 } else { /* SerDes */
4121                         DP(NETIF_MSG_LINK, "SerDes phy link up\n");
4122                         /* Disable the link interrupt
4123                          * by writing 1 to the status register
4124                          */
4125                         bnx2x_bits_en(bp,
4126                                       NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4127                                       NIG_STATUS_SERDES0_LINK_STATUS);
4128                 }
4129
4130         } else { /* link_down */
4131         }
4132 }
4133
4134 static u8 bnx2x_format_ver(u32 num, u8 *str, u16 len)
4135 {
4136         u8 *str_ptr = str;
4137         u32 mask = 0xf0000000;
4138         u8 shift = 8*4;
4139         u8 digit;
4140         if (len < 10) {
4141                 /* Need more than 10chars for this format */
4142                 *str_ptr = '\0';
4143                 return -EINVAL;
4144         }
4145         while (shift > 0) {
4146
4147                 shift -= 4;
4148                 digit = ((num & mask) >> shift);
4149                 if (digit < 0xa)
4150                         *str_ptr = digit + '0';
4151                 else
4152                         *str_ptr = digit - 0xa + 'a';
4153                 str_ptr++;
4154                 mask = mask >> 4;
4155                 if (shift == 4*4) {
4156                         *str_ptr = ':';
4157                         str_ptr++;
4158                 }
4159         }
4160         *str_ptr = '\0';
4161         return 0;
4162 }
4163
4164
4165 static void bnx2x_turn_on_ef(struct bnx2x *bp, u8 port, u8 ext_phy_addr,
4166                            u32 ext_phy_type)
4167 {
4168         u32 cnt = 0;
4169         u16 ctrl = 0;
4170         /* Enable EMAC0 in to enable MDIO */
4171         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
4172                (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
4173         msleep(5);
4174
4175         /* take ext phy out of reset */
4176         bnx2x_set_gpio(bp,
4177                           MISC_REGISTERS_GPIO_2,
4178                           MISC_REGISTERS_GPIO_HIGH,
4179                           port);
4180
4181         bnx2x_set_gpio(bp,
4182                           MISC_REGISTERS_GPIO_1,
4183                           MISC_REGISTERS_GPIO_HIGH,
4184                           port);
4185
4186         /* wait for 5ms */
4187         msleep(5);
4188
4189         for (cnt = 0; cnt < 1000; cnt++) {
4190                 msleep(1);
4191                 bnx2x_cl45_read(bp, port,
4192                               ext_phy_type,
4193                               ext_phy_addr,
4194                               MDIO_PMA_DEVAD,
4195                               MDIO_PMA_REG_CTRL,
4196                               &ctrl);
4197                 if (!(ctrl & (1<<15))) {
4198                         DP(NETIF_MSG_LINK, "Reset completed\n\n");
4199                                 break;
4200                 }
4201         }
4202 }
4203
4204 static void bnx2x_turn_off_sf(struct bnx2x *bp, u8 port)
4205 {
4206         /* put sf to reset */
4207         bnx2x_set_gpio(bp,
4208                           MISC_REGISTERS_GPIO_1,
4209                           MISC_REGISTERS_GPIO_LOW,
4210                           port);
4211         bnx2x_set_gpio(bp,
4212                           MISC_REGISTERS_GPIO_2,
4213                           MISC_REGISTERS_GPIO_LOW,
4214                           port);
4215 }
4216
4217 u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
4218                               u8 *version, u16 len)
4219 {
4220         struct bnx2x *bp = params->bp;
4221         u32 ext_phy_type = 0;
4222         u32 spirom_ver = 0;
4223         u8 status = 0 ;
4224
4225         if (version == NULL || params == NULL)
4226                 return -EINVAL;
4227
4228         spirom_ver = REG_RD(bp, params->shmem_base +
4229                    offsetof(struct shmem_region,
4230                             port_mb[params->port].ext_phy_fw_version));
4231
4232         /* reset the returned value to zero */
4233         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4234         switch (ext_phy_type) {
4235         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4236
4237                 if (len < 5)
4238                         return -EINVAL;
4239
4240                 version[0] = (spirom_ver & 0xFF);
4241                 version[1] = (spirom_ver & 0xFF00) >> 8;
4242                 version[2] = (spirom_ver & 0xFF0000) >> 16;
4243                 version[3] = (spirom_ver & 0xFF000000) >> 24;
4244                 version[4] = '\0';
4245
4246                 break;
4247         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4248         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4249         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
4250         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
4251         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
4252                 status = bnx2x_format_ver(spirom_ver, version, len);
4253                 break;
4254         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4255                 break;
4256
4257         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
4258                 DP(NETIF_MSG_LINK, "bnx2x_get_ext_phy_fw_version:"
4259                                     " type is FAILURE!\n");
4260                 status = -EINVAL;
4261                 break;
4262
4263         default:
4264                 break;
4265         }
4266         return status;
4267 }
4268
4269 static void bnx2x_set_xgxs_loopback(struct link_params *params,
4270                                   struct link_vars *vars,
4271                                   u8 is_10g)
4272 {
4273         u8 port = params->port;
4274         struct bnx2x *bp = params->bp;
4275
4276         if (is_10g) {
4277                 u32 md_devad;
4278
4279                 DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
4280
4281                 /* change the uni_phy_addr in the nig */
4282                 md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
4283                                           port*0x18));
4284
4285                 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
4286
4287                 bnx2x_cl45_write(bp, port, 0,
4288                                params->phy_addr,
4289                                5,
4290                                (MDIO_REG_BANK_AER_BLOCK +
4291                                 (MDIO_AER_BLOCK_AER_REG & 0xf)),
4292                                0x2800);
4293
4294                 bnx2x_cl45_write(bp, port, 0,
4295                                params->phy_addr,
4296                                5,
4297                                (MDIO_REG_BANK_CL73_IEEEB0 +
4298                                 (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
4299                                0x6041);
4300                 msleep(200);
4301                 /* set aer mmd back */
4302                 bnx2x_set_aer_mmd(params, vars);
4303
4304                 /* and md_devad */
4305                 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
4306                             md_devad);
4307
4308         } else {
4309                 u16 mii_control;
4310
4311                 DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
4312
4313                 CL45_RD_OVER_CL22(bp, port,
4314                                       params->phy_addr,
4315                                       MDIO_REG_BANK_COMBO_IEEE0,
4316                                       MDIO_COMBO_IEEE0_MII_CONTROL,
4317                                       &mii_control);
4318
4319                 CL45_WR_OVER_CL22(bp, port,
4320                                       params->phy_addr,
4321                                       MDIO_REG_BANK_COMBO_IEEE0,
4322                                       MDIO_COMBO_IEEE0_MII_CONTROL,
4323                                       (mii_control |
4324                                        MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK));
4325         }
4326 }
4327
4328
4329 static void bnx2x_ext_phy_loopback(struct link_params *params)
4330 {
4331         struct bnx2x *bp = params->bp;
4332         u8 ext_phy_addr;
4333         u32 ext_phy_type;
4334
4335         if (params->switch_cfg == SWITCH_CFG_10G) {
4336                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4337                 /* CL37 Autoneg Enabled */
4338                 ext_phy_addr = ((params->ext_phy_config &
4339                                         PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4340                                         PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4341                 switch (ext_phy_type) {
4342                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4343                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
4344                         DP(NETIF_MSG_LINK,
4345                                 "ext_phy_loopback: We should not get here\n");
4346                         break;
4347                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
4348                         DP(NETIF_MSG_LINK, "ext_phy_loopback: 8705\n");
4349                         break;
4350                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
4351                         DP(NETIF_MSG_LINK, "ext_phy_loopback: 8706\n");
4352                         break;
4353                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
4354                         DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
4355                         bnx2x_cl45_write(bp, params->port, ext_phy_type,
4356                                        ext_phy_addr,
4357                                        MDIO_PMA_DEVAD,
4358                                        MDIO_PMA_REG_CTRL,
4359                                        0x0001);
4360                         break;
4361                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4362                         /* SFX7101_XGXS_TEST1 */
4363                         bnx2x_cl45_write(bp, params->port, ext_phy_type,
4364                                        ext_phy_addr,
4365                                        MDIO_XS_DEVAD,
4366                                        MDIO_XS_SFX7101_XGXS_TEST1,
4367                                        0x100);
4368                         DP(NETIF_MSG_LINK,
4369                                 "ext_phy_loopback: set ext phy loopback\n");
4370                         break;
4371                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4372
4373                         break;
4374                 } /* switch external PHY type */
4375         } else {
4376                 /* serdes */
4377                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
4378                 ext_phy_addr = (params->ext_phy_config  &
4379                 PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK)
4380                 >> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT;
4381         }
4382 }
4383
4384
4385 /*
4386  *------------------------------------------------------------------------
4387  * bnx2x_override_led_value -
4388  *
4389  * Override the led value of the requsted led
4390  *
4391  *------------------------------------------------------------------------
4392  */
4393 u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port,
4394                           u32 led_idx, u32 value)
4395 {
4396         u32 reg_val;
4397
4398         /* If port 0 then use EMAC0, else use EMAC1*/
4399         u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
4400
4401         DP(NETIF_MSG_LINK,
4402                  "bnx2x_override_led_value() port %x led_idx %d value %d\n",
4403                  port, led_idx, value);
4404
4405         switch (led_idx) {
4406         case 0: /* 10MB led */
4407                 /* Read the current value of the LED register in
4408                 the EMAC block */
4409                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4410                 /* Set the OVERRIDE bit to 1 */
4411                 reg_val |= EMAC_LED_OVERRIDE;
4412                 /* If value is 1, set the 10M_OVERRIDE bit,
4413                 otherwise reset it.*/
4414                 reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) :
4415                         (reg_val & ~EMAC_LED_10MB_OVERRIDE);
4416                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4417                 break;
4418         case 1: /*100MB led    */
4419                 /*Read the current value of the LED register in
4420                 the EMAC block */
4421                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4422                 /*  Set the OVERRIDE bit to 1 */
4423                 reg_val |= EMAC_LED_OVERRIDE;
4424                 /*  If value is 1, set the 100M_OVERRIDE bit,
4425                 otherwise reset it.*/
4426                 reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) :
4427                         (reg_val & ~EMAC_LED_100MB_OVERRIDE);
4428                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4429                 break;
4430         case 2: /* 1000MB led */
4431                 /* Read the current value of the LED register in the
4432                 EMAC block */
4433                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4434                 /* Set the OVERRIDE bit to 1 */
4435                 reg_val |= EMAC_LED_OVERRIDE;
4436                 /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
4437                 reset it. */
4438                 reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) :
4439                         (reg_val & ~EMAC_LED_1000MB_OVERRIDE);
4440                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4441                 break;
4442         case 3: /* 2500MB led */
4443                 /*  Read the current value of the LED register in the
4444                 EMAC block*/
4445                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4446                 /* Set the OVERRIDE bit to 1 */
4447                 reg_val |= EMAC_LED_OVERRIDE;
4448                 /*  If value is 1, set the 2500M_OVERRIDE bit, otherwise
4449                 reset it.*/
4450                 reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) :
4451                         (reg_val & ~EMAC_LED_2500MB_OVERRIDE);
4452                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4453                 break;
4454         case 4: /*10G led */
4455                 if (port == 0) {
4456                         REG_WR(bp, NIG_REG_LED_10G_P0,
4457                                     value);
4458                 } else {
4459                         REG_WR(bp, NIG_REG_LED_10G_P1,
4460                                     value);
4461                 }
4462                 break;
4463         case 5: /* TRAFFIC led */
4464                 /* Find if the traffic control is via BMAC or EMAC */
4465                 if (port == 0)
4466                         reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN);
4467                 else
4468                         reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN);
4469
4470                 /*  Override the traffic led in the EMAC:*/
4471                 if (reg_val == 1) {
4472                         /* Read the current value of the LED register in
4473                         the EMAC block */
4474                         reg_val = REG_RD(bp, emac_base +
4475                                              EMAC_REG_EMAC_LED);
4476                         /* Set the TRAFFIC_OVERRIDE bit to 1 */
4477                         reg_val |= EMAC_LED_OVERRIDE;
4478                         /* If value is 1, set the TRAFFIC bit, otherwise
4479                         reset it.*/
4480                         reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) :
4481                                 (reg_val & ~EMAC_LED_TRAFFIC);
4482                         REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4483                 } else { /* Override the traffic led in the BMAC: */
4484                         REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
4485                                    + port*4, 1);
4486                         REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4,
4487                                     value);
4488                 }
4489                 break;
4490         default:
4491                 DP(NETIF_MSG_LINK,
4492                          "bnx2x_override_led_value() unknown led index %d "
4493                          "(should be 0-5)\n", led_idx);
4494                 return -EINVAL;
4495         }
4496
4497         return 0;
4498 }
4499
4500
4501 u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed,
4502                u16 hw_led_mode, u32 chip_id)
4503 {
4504         u8 rc = 0;
4505         u32 tmp;
4506         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
4507         DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
4508         DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
4509                  speed, hw_led_mode);
4510         switch (mode) {
4511         case LED_MODE_OFF:
4512                 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
4513                 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
4514                            SHARED_HW_CFG_LED_MAC1);
4515
4516                 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
4517                 EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
4518                 break;
4519
4520         case LED_MODE_OPER:
4521                 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode);
4522                 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 +
4523                            port*4, 0);
4524                 /* Set blinking rate to ~15.9Hz */
4525                 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
4526                            LED_BLINK_RATE_VAL);
4527                 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
4528                            port*4, 1);
4529                 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
4530                 EMAC_WR(bp, EMAC_REG_EMAC_LED,
4531                             (tmp & (~EMAC_LED_OVERRIDE)));
4532
4533                 if (!CHIP_IS_E1H(bp) &&
4534                     ((speed == SPEED_2500) ||
4535                      (speed == SPEED_1000) ||
4536                      (speed == SPEED_100) ||
4537                      (speed == SPEED_10))) {
4538                         /* On Everest 1 Ax chip versions for speeds less than
4539                         10G LED scheme is different */
4540                         REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
4541                                    + port*4, 1);
4542                         REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
4543                                    port*4, 0);
4544                         REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
4545                                    port*4, 1);
4546                 }
4547                 break;
4548
4549         default:
4550                 rc = -EINVAL;
4551                 DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
4552                          mode);
4553                 break;
4554         }
4555         return rc;
4556
4557 }
4558
4559 u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars)
4560 {
4561         struct bnx2x *bp = params->bp;
4562         u16 gp_status = 0;
4563
4564         CL45_RD_OVER_CL22(bp, params->port,
4565                               params->phy_addr,
4566                               MDIO_REG_BANK_GP_STATUS,
4567                               MDIO_GP_STATUS_TOP_AN_STATUS1,
4568                               &gp_status);
4569         /* link is up only if both local phy and external phy are up */
4570         if ((gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) &&
4571             bnx2x_ext_phy_is_link_up(params, vars))
4572                 return 0;
4573
4574         return -ESRCH;
4575 }
4576
4577 static u8 bnx2x_link_initialize(struct link_params *params,
4578                               struct link_vars *vars)
4579 {
4580         struct bnx2x *bp = params->bp;
4581         u8 port = params->port;
4582         u8 rc = 0;
4583         u8 non_ext_phy;
4584         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4585         /* Activate the external PHY */
4586         bnx2x_ext_phy_reset(params, vars);
4587
4588         bnx2x_set_aer_mmd(params, vars);
4589
4590         if (vars->phy_flags & PHY_XGXS_FLAG)
4591                 bnx2x_set_master_ln(params);
4592
4593         rc = bnx2x_reset_unicore(params);
4594         /* reset the SerDes and wait for reset bit return low */
4595         if (rc != 0)
4596                 return rc;
4597
4598         bnx2x_set_aer_mmd(params, vars);
4599
4600         /* setting the masterLn_def again after the reset */
4601         if (vars->phy_flags & PHY_XGXS_FLAG) {
4602                 bnx2x_set_master_ln(params);
4603                 bnx2x_set_swap_lanes(params);
4604         }
4605
4606         if (vars->phy_flags & PHY_XGXS_FLAG) {
4607                 if ((params->req_line_speed &&
4608                     ((params->req_line_speed == SPEED_100) ||
4609                      (params->req_line_speed == SPEED_10))) ||
4610                     (!params->req_line_speed &&
4611                      (params->speed_cap_mask >=
4612                        PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
4613                      (params->speed_cap_mask <
4614                        PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
4615                      ))  {
4616                         vars->phy_flags |= PHY_SGMII_FLAG;
4617                 } else {
4618                         vars->phy_flags &= ~PHY_SGMII_FLAG;
4619                 }
4620         }
4621         /* In case of external phy existance, the line speed would be the
4622          line speed linked up by the external phy. In case it is direct only,
4623           then the line_speed during initialization will be equal to the
4624            req_line_speed*/
4625         vars->line_speed = params->req_line_speed;
4626
4627         bnx2x_calc_ieee_aneg_adv(params, &vars->ieee_fc);
4628
4629         /* init ext phy and enable link state int */
4630         non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
4631                        (params->loopback_mode == LOOPBACK_XGXS_10) ||
4632                        (params->loopback_mode == LOOPBACK_EXT_PHY));
4633
4634         if (non_ext_phy ||
4635             (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
4636             (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) ||
4637             (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481)) {
4638                 if (params->req_line_speed == SPEED_AUTO_NEG)
4639                         bnx2x_set_parallel_detection(params, vars->phy_flags);
4640                 bnx2x_init_internal_phy(params, vars);
4641         }
4642
4643         if (!non_ext_phy)
4644                 rc |= bnx2x_ext_phy_init(params, vars);
4645
4646         bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4647                      (NIG_STATUS_XGXS0_LINK10G |
4648                       NIG_STATUS_XGXS0_LINK_STATUS |
4649                       NIG_STATUS_SERDES0_LINK_STATUS));
4650
4651         return rc;
4652
4653 }
4654
4655
4656 u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
4657 {
4658         struct bnx2x *bp = params->bp;
4659
4660         u32 val;
4661         DP(NETIF_MSG_LINK, "Phy Initialization started \n");
4662         DP(NETIF_MSG_LINK, "req_speed = %d, req_flowctrl=%d\n",
4663                   params->req_line_speed, params->req_flow_ctrl);
4664         vars->link_status = 0;
4665         vars->phy_link_up = 0;
4666         vars->link_up = 0;
4667         vars->line_speed = 0;
4668         vars->duplex = DUPLEX_FULL;
4669         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4670         vars->mac_type = MAC_TYPE_NONE;
4671
4672         if (params->switch_cfg ==  SWITCH_CFG_1G)
4673                 vars->phy_flags = PHY_SERDES_FLAG;
4674         else
4675                 vars->phy_flags = PHY_XGXS_FLAG;
4676
4677
4678         /* disable attentions */
4679         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
4680                        (NIG_MASK_XGXS0_LINK_STATUS |
4681                         NIG_MASK_XGXS0_LINK10G |
4682                         NIG_MASK_SERDES0_LINK_STATUS |
4683                         NIG_MASK_MI_INT));
4684
4685         bnx2x_emac_init(params, vars);
4686
4687         if (CHIP_REV_IS_FPGA(bp)) {
4688                 vars->link_up = 1;
4689                 vars->line_speed = SPEED_10000;
4690                 vars->duplex = DUPLEX_FULL;
4691                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4692                 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
4693                 /* enable on E1.5 FPGA */
4694                 if (CHIP_IS_E1H(bp)) {
4695                         vars->flow_ctrl |=
4696                                 (BNX2X_FLOW_CTRL_TX | BNX2X_FLOW_CTRL_RX);
4697                         vars->link_status |=
4698                                         (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
4699                                          LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
4700                 }
4701
4702                 bnx2x_emac_enable(params, vars, 0);
4703                 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
4704                 /* disable drain */
4705                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
4706                                     + params->port*4, 0);
4707
4708                 /* update shared memory */
4709                 bnx2x_update_mng(params, vars->link_status);
4710
4711                 return 0;
4712
4713         } else
4714         if (CHIP_REV_IS_EMUL(bp)) {
4715
4716                 vars->link_up = 1;
4717                 vars->line_speed = SPEED_10000;
4718                 vars->duplex = DUPLEX_FULL;
4719                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4720                 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
4721
4722                 bnx2x_bmac_enable(params, vars, 0);
4723
4724                 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
4725                 /* Disable drain */
4726                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
4727                                     + params->port*4, 0);
4728
4729                 /* update shared memory */
4730                 bnx2x_update_mng(params, vars->link_status);
4731
4732                 return 0;
4733
4734         } else
4735         if (params->loopback_mode == LOOPBACK_BMAC) {
4736                 vars->link_up = 1;
4737                 vars->line_speed = SPEED_10000;
4738                 vars->duplex = DUPLEX_FULL;
4739                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4740                 vars->mac_type = MAC_TYPE_BMAC;
4741
4742                 vars->phy_flags = PHY_XGXS_FLAG;
4743
4744                 bnx2x_phy_deassert(params, vars->phy_flags);
4745                 /* set bmac loopback */
4746                 bnx2x_bmac_enable(params, vars, 1);
4747
4748                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4749                     params->port*4, 0);
4750         } else if (params->loopback_mode == LOOPBACK_EMAC) {
4751                 vars->link_up = 1;
4752                 vars->line_speed = SPEED_1000;
4753                 vars->duplex = DUPLEX_FULL;
4754                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4755                 vars->mac_type = MAC_TYPE_EMAC;
4756
4757                 vars->phy_flags = PHY_XGXS_FLAG;
4758
4759                 bnx2x_phy_deassert(params, vars->phy_flags);
4760                 /* set bmac loopback */
4761                 bnx2x_emac_enable(params, vars, 1);
4762                 bnx2x_emac_program(params, vars->line_speed,
4763                                               vars->duplex);
4764                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4765                     params->port*4, 0);
4766         } else if ((params->loopback_mode == LOOPBACK_XGXS_10) ||
4767                   (params->loopback_mode == LOOPBACK_EXT_PHY)) {
4768                 vars->link_up = 1;
4769                 vars->line_speed = SPEED_10000;
4770                 vars->duplex = DUPLEX_FULL;
4771                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4772
4773                 vars->phy_flags = PHY_XGXS_FLAG;
4774
4775                 val = REG_RD(bp,
4776                                  NIG_REG_XGXS0_CTRL_PHY_ADDR+
4777                                  params->port*0x18);
4778                 params->phy_addr = (u8)val;
4779
4780                 bnx2x_phy_deassert(params, vars->phy_flags);
4781                 bnx2x_link_initialize(params, vars);
4782
4783                 vars->mac_type = MAC_TYPE_BMAC;
4784
4785                 bnx2x_bmac_enable(params, vars, 0);
4786
4787                 if (params->loopback_mode == LOOPBACK_XGXS_10) {
4788                         /* set 10G XGXS loopback */
4789                         bnx2x_set_xgxs_loopback(params, vars, 1);
4790                 } else {
4791                         /* set external phy loopback */
4792                         bnx2x_ext_phy_loopback(params);
4793                 }
4794                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4795                             params->port*4, 0);
4796         } else
4797         /* No loopback */
4798         {
4799
4800                 bnx2x_phy_deassert(params, vars->phy_flags);
4801                 switch (params->switch_cfg) {
4802                 case SWITCH_CFG_1G:
4803                         vars->phy_flags |= PHY_SERDES_FLAG;
4804                         if ((params->ext_phy_config &
4805                              PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) ==
4806                              PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482) {
4807                                 vars->phy_flags |=
4808                                         PHY_SGMII_FLAG;
4809                         }
4810
4811                         val = REG_RD(bp,
4812                                          NIG_REG_SERDES0_CTRL_PHY_ADDR+
4813                                          params->port*0x10);
4814
4815                         params->phy_addr = (u8)val;
4816
4817                         break;
4818                 case SWITCH_CFG_10G:
4819                         vars->phy_flags |= PHY_XGXS_FLAG;
4820                         val = REG_RD(bp,
4821                                  NIG_REG_XGXS0_CTRL_PHY_ADDR+
4822                                  params->port*0x18);
4823                         params->phy_addr = (u8)val;
4824
4825                         break;
4826                 default:
4827                         DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
4828                         return -EINVAL;
4829                         break;
4830                 }
4831                 DP(NETIF_MSG_LINK, "Phy address = 0x%x\n", params->phy_addr);
4832
4833                 bnx2x_link_initialize(params, vars);
4834                 msleep(30);
4835                 bnx2x_link_int_enable(params);
4836         }
4837         return 0;
4838 }
4839
4840 static void bnx2x_8726_reset_phy(struct bnx2x *bp, u8 port, u8 ext_phy_addr)
4841 {
4842         DP(NETIF_MSG_LINK, "bnx2x_8726_reset_phy port %d\n", port);
4843
4844         /* Set serial boot control for external load */
4845         bnx2x_cl45_write(bp, port,
4846                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, ext_phy_addr,
4847                        MDIO_PMA_DEVAD,
4848                        MDIO_PMA_REG_GEN_CTRL, 0x0001);
4849
4850         /* Disable Transmitter */
4851         bnx2x_bcm8726_set_transmitter(bp, port, ext_phy_addr, 0);
4852
4853 }
4854
4855 u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
4856                   u8 reset_ext_phy)
4857 {
4858
4859         struct bnx2x *bp = params->bp;
4860         u32 ext_phy_config = params->ext_phy_config;
4861         u16 hw_led_mode = params->hw_led_mode;
4862         u32 chip_id = params->chip_id;
4863         u8 port = params->port;
4864         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
4865         /* disable attentions */
4866
4867         vars->link_status = 0;
4868         bnx2x_update_mng(params, vars->link_status);
4869         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
4870                      (NIG_MASK_XGXS0_LINK_STATUS |
4871                       NIG_MASK_XGXS0_LINK10G |
4872                       NIG_MASK_SERDES0_LINK_STATUS |
4873                       NIG_MASK_MI_INT));
4874
4875         /* activate nig drain */
4876         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
4877
4878         /* disable nig egress interface */
4879         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
4880         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
4881
4882         /* Stop BigMac rx */
4883         bnx2x_bmac_rx_disable(bp, port);
4884
4885         /* disable emac */
4886         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
4887
4888         msleep(10);
4889         /* The PHY reset is controled by GPIO 1
4890          * Hold it as vars low
4891          */
4892          /* clear link led */
4893         bnx2x_set_led(bp, port, LED_MODE_OFF, 0, hw_led_mode, chip_id);
4894         if (reset_ext_phy) {
4895                 switch (ext_phy_type) {
4896                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4897                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4898                         break;
4899                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4900                         DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
4901                                  "low power mode\n",
4902                                  port);
4903                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4904                                           MISC_REGISTERS_GPIO_OUTPUT_LOW,
4905                                           port);
4906                         break;
4907                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
4908                 {
4909                         u8 ext_phy_addr = ((params->ext_phy_config &
4910                                          PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4911                                          PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4912                         /* Set soft reset */
4913                         bnx2x_8726_reset_phy(bp, params->port, ext_phy_addr);
4914                         break;
4915                 }
4916                 default:
4917                         /* HW reset */
4918                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
4919                                           MISC_REGISTERS_GPIO_OUTPUT_LOW,
4920                                           port);
4921                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4922                                           MISC_REGISTERS_GPIO_OUTPUT_LOW,
4923                                           port);
4924                         DP(NETIF_MSG_LINK, "reset external PHY\n");
4925                 }
4926         }
4927         /* reset the SerDes/XGXS */
4928         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
4929                (0x1ff << (port*16)));
4930
4931         /* reset BigMac */
4932         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
4933                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4934
4935         /* disable nig ingress interface */
4936         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
4937         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
4938         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
4939         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
4940         vars->link_up = 0;
4941         return 0;
4942 }
4943
4944 static u8 bnx2x_update_link_down(struct link_params *params,
4945                                struct link_vars *vars)
4946 {
4947         struct bnx2x *bp = params->bp;
4948         u8 port = params->port;
4949         DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
4950         bnx2x_set_led(bp, port, LED_MODE_OFF,
4951                     0, params->hw_led_mode,
4952                     params->chip_id);
4953
4954         /* indicate no mac active */
4955         vars->mac_type = MAC_TYPE_NONE;
4956
4957         /* update shared memory */
4958         vars->link_status = 0;
4959         vars->line_speed = 0;
4960         bnx2x_update_mng(params, vars->link_status);
4961
4962         /* activate nig drain */
4963         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
4964
4965         /* disable emac */
4966         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
4967
4968         msleep(10);
4969
4970         /* reset BigMac */
4971         bnx2x_bmac_rx_disable(bp, params->port);
4972         REG_WR(bp, GRCBASE_MISC +
4973                    MISC_REGISTERS_RESET_REG_2_CLEAR,
4974                    (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4975         return 0;
4976 }
4977
4978 static u8 bnx2x_update_link_up(struct link_params *params,
4979                              struct link_vars *vars,
4980                              u8 link_10g, u32 gp_status)
4981 {
4982         struct bnx2x *bp = params->bp;
4983         u8 port = params->port;
4984         u8 rc = 0;
4985         vars->link_status |= LINK_STATUS_LINK_UP;
4986         if (link_10g) {
4987                 bnx2x_bmac_enable(params, vars, 0);
4988                 bnx2x_set_led(bp, port, LED_MODE_OPER,
4989                             SPEED_10000, params->hw_led_mode,
4990                             params->chip_id);
4991
4992         } else {
4993                 bnx2x_emac_enable(params, vars, 0);
4994                 rc = bnx2x_emac_program(params, vars->line_speed,
4995                                       vars->duplex);
4996
4997                 /* AN complete? */
4998                 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
4999                         if (!(vars->phy_flags &
5000                               PHY_SGMII_FLAG))
5001                                 bnx2x_set_gmii_tx_driver(params);
5002                 }
5003         }
5004
5005         /* PBF - link up */
5006         rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
5007                               vars->line_speed);
5008
5009         /* disable drain */
5010         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
5011
5012         /* update shared memory */
5013         bnx2x_update_mng(params, vars->link_status);
5014         msleep(20);
5015         return rc;
5016 }
5017 /* This function should called upon link interrupt */
5018 /* In case vars->link_up, driver needs to
5019         1. Update the pbf
5020         2. Disable drain
5021         3. Update the shared memory
5022         4. Indicate link up
5023         5. Set LEDs
5024    Otherwise,
5025         1. Update shared memory
5026         2. Reset BigMac
5027         3. Report link down
5028         4. Unset LEDs
5029 */
5030 u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
5031 {
5032         struct bnx2x *bp = params->bp;
5033         u8 port = params->port;
5034         u16 gp_status;
5035         u8 link_10g;
5036         u8 ext_phy_link_up, rc = 0;
5037         u32 ext_phy_type;
5038
5039         DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
5040          port,
5041         (vars->phy_flags & PHY_XGXS_FLAG),
5042          REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
5043
5044         DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
5045         REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
5046         REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
5047         REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
5048
5049         DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
5050           REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
5051           REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
5052
5053         /* disable emac */
5054         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
5055
5056         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
5057
5058         /* Check external link change only for non-direct */
5059         ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars);
5060
5061         /* Read gp_status */
5062         CL45_RD_OVER_CL22(bp, port, params->phy_addr,
5063                               MDIO_REG_BANK_GP_STATUS,
5064                               MDIO_GP_STATUS_TOP_AN_STATUS1,
5065                               &gp_status);
5066
5067         rc = bnx2x_link_settings_status(params, vars, gp_status);
5068         if (rc != 0)
5069                 return rc;
5070
5071         /* anything 10 and over uses the bmac */
5072         link_10g = ((vars->line_speed == SPEED_10000) ||
5073                     (vars->line_speed == SPEED_12000) ||
5074                     (vars->line_speed == SPEED_12500) ||
5075                     (vars->line_speed == SPEED_13000) ||
5076                     (vars->line_speed == SPEED_15000) ||
5077                     (vars->line_speed == SPEED_16000));
5078
5079         bnx2x_link_int_ack(params, vars, link_10g);
5080
5081         /* In case external phy link is up, and internal link is down
5082         ( not initialized yet probably after link initialization, it needs
5083         to be initialized.
5084         Note that after link down-up as result of cable plug,
5085         the xgxs link would probably become up again without the need to
5086         initialize it*/
5087
5088         if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
5089             (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
5090             (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) &&
5091             (ext_phy_link_up && !vars->phy_link_up))
5092                 bnx2x_init_internal_phy(params, vars);
5093
5094         /* link is up only if both local phy and external phy are up */
5095         vars->link_up = (ext_phy_link_up && vars->phy_link_up);
5096
5097         if (vars->link_up)
5098                 rc = bnx2x_update_link_up(params, vars, link_10g, gp_status);
5099         else
5100                 rc = bnx2x_update_link_down(params, vars);
5101
5102         return rc;
5103 }
5104
5105 static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
5106 {
5107         u8 ext_phy_addr[PORT_MAX];
5108         u16 val;
5109         s8 port;
5110
5111         /* PART1 - Reset both phys */
5112         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
5113                 /* Extract the ext phy address for the port */
5114                 u32 ext_phy_config = REG_RD(bp, shmem_base +
5115                                         offsetof(struct shmem_region,
5116                    dev_info.port_hw_config[port].external_phy_config));
5117
5118                 /* disable attentions */
5119                 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
5120                              (NIG_MASK_XGXS0_LINK_STATUS |
5121                               NIG_MASK_XGXS0_LINK10G |
5122                               NIG_MASK_SERDES0_LINK_STATUS |
5123                               NIG_MASK_MI_INT));
5124
5125                 ext_phy_addr[port] =
5126                         ((ext_phy_config &
5127                               PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
5128                               PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
5129
5130                 /* Need to take the phy out of low power mode in order
5131                         to write to access its registers */
5132                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5133                                   MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
5134
5135                 /* Reset the phy */
5136                 bnx2x_cl45_write(bp, port,
5137                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5138                                ext_phy_addr[port],
5139                                MDIO_PMA_DEVAD,
5140                                MDIO_PMA_REG_CTRL,
5141                                1<<15);
5142         }
5143
5144         /* Add delay of 150ms after reset */
5145         msleep(150);
5146
5147         /* PART2 - Download firmware to both phys */
5148         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
5149                 u16 fw_ver1;
5150
5151                 bnx2x_bcm8073_external_rom_boot(bp, port,
5152                                               ext_phy_addr[port], shmem_base);
5153
5154                 bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5155                               ext_phy_addr[port],
5156                               MDIO_PMA_DEVAD,
5157                               MDIO_PMA_REG_ROM_VER1, &fw_ver1);
5158                 if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
5159                         DP(NETIF_MSG_LINK,
5160                                  "bnx2x_8073_common_init_phy port %x:"
5161                                  "Download failed. fw version = 0x%x\n",
5162                                  port, fw_ver1);
5163                         return -EINVAL;
5164                 }
5165
5166                 /* Only set bit 10 = 1 (Tx power down) */
5167                 bnx2x_cl45_read(bp, port,
5168                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5169                               ext_phy_addr[port],
5170                               MDIO_PMA_DEVAD,
5171                               MDIO_PMA_REG_TX_POWER_DOWN, &val);
5172
5173                 /* Phase1 of TX_POWER_DOWN reset */
5174                 bnx2x_cl45_write(bp, port,
5175                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5176                                ext_phy_addr[port],
5177                                MDIO_PMA_DEVAD,
5178                                MDIO_PMA_REG_TX_POWER_DOWN,
5179                                (val | 1<<10));
5180         }
5181
5182         /* Toggle Transmitter: Power down and then up with 600ms
5183            delay between */
5184         msleep(600);
5185
5186         /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
5187         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
5188                 /* Phase2 of POWER_DOWN_RESET */
5189                 /* Release bit 10 (Release Tx power down) */
5190                 bnx2x_cl45_read(bp, port,
5191                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5192                               ext_phy_addr[port],
5193                               MDIO_PMA_DEVAD,
5194                               MDIO_PMA_REG_TX_POWER_DOWN, &val);
5195
5196                 bnx2x_cl45_write(bp, port,
5197                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5198                                ext_phy_addr[port],
5199                                MDIO_PMA_DEVAD,
5200                                MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
5201                 msleep(15);
5202
5203                 /* Read modify write the SPI-ROM version select register */
5204                 bnx2x_cl45_read(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);
5209                 bnx2x_cl45_write(bp, port,
5210                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5211                               ext_phy_addr[port],
5212                               MDIO_PMA_DEVAD,
5213                               MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
5214
5215                 /* set GPIO2 back to LOW */
5216                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5217                                   MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
5218         }
5219         return 0;
5220
5221 }
5222
5223
5224 static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base)
5225 {
5226         u8 ext_phy_addr;
5227         u32 val;
5228         s8 port;
5229         /* Use port1 because of the static port-swap */
5230         /* Enable the module detection interrupt */
5231         val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
5232         val |= ((1<<MISC_REGISTERS_GPIO_3)|
5233                 (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
5234         REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
5235
5236         bnx2x_hw_reset(bp, 1);
5237         msleep(5);
5238         for (port = 0; port < PORT_MAX; port++) {
5239                 /* Extract the ext phy address for the port */
5240                 u32 ext_phy_config = REG_RD(bp, shmem_base +
5241                                         offsetof(struct shmem_region,
5242                         dev_info.port_hw_config[port].external_phy_config));
5243
5244                 ext_phy_addr =
5245                         ((ext_phy_config &
5246                               PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
5247                               PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
5248                 DP(NETIF_MSG_LINK, "8726_common_init : ext_phy_addr = 0x%x\n",
5249                          ext_phy_addr);
5250
5251                 bnx2x_8726_reset_phy(bp, port, ext_phy_addr);
5252
5253                 /* Set fault module detected LED on */
5254                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
5255                                   MISC_REGISTERS_GPIO_HIGH,
5256                                   port);
5257         }
5258
5259         return 0;
5260 }
5261
5262 u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
5263 {
5264         u8 rc = 0;
5265         u32 ext_phy_type;
5266
5267         DP(NETIF_MSG_LINK, "Begin common phy init\n");
5268
5269         /* Read the ext_phy_type for arbitrary port(0) */
5270         ext_phy_type = XGXS_EXT_PHY_TYPE(
5271                         REG_RD(bp, shmem_base +
5272                            offsetof(struct shmem_region,
5273                              dev_info.port_hw_config[0].external_phy_config)));
5274
5275         switch (ext_phy_type) {
5276         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
5277         {
5278                 rc = bnx2x_8073_common_init_phy(bp, shmem_base);
5279                 break;
5280         }
5281         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
5282                 /* GPIO1 affects both ports, so there's need to pull
5283                 it for single port alone */
5284                 rc = bnx2x_8726_common_init_phy(bp, shmem_base);
5285
5286                 break;
5287         default:
5288                 DP(NETIF_MSG_LINK,
5289                          "bnx2x_common_init_phy: ext_phy 0x%x not required\n",
5290                          ext_phy_type);
5291                 break;
5292         }
5293
5294         return rc;
5295 }
5296
5297
5298
5299 static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
5300 {
5301         u16 val, cnt;
5302
5303         bnx2x_cl45_read(bp, port,
5304                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5305                       phy_addr,
5306                       MDIO_PMA_DEVAD,
5307                       MDIO_PMA_REG_7101_RESET, &val);
5308
5309         for (cnt = 0; cnt < 10; cnt++) {
5310                 msleep(50);
5311                 /* Writes a self-clearing reset */
5312                 bnx2x_cl45_write(bp, port,
5313                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5314                                phy_addr,
5315                                MDIO_PMA_DEVAD,
5316                                MDIO_PMA_REG_7101_RESET,
5317                                (val | (1<<15)));
5318                 /* Wait for clear */
5319                 bnx2x_cl45_read(bp, port,
5320                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5321                               phy_addr,
5322                               MDIO_PMA_DEVAD,
5323                               MDIO_PMA_REG_7101_RESET, &val);
5324
5325                 if ((val & (1<<15)) == 0)
5326                         break;
5327         }
5328 }
5329 #define RESERVED_SIZE 256
5330 /* max application is 160K bytes - data at end of RAM */
5331 #define MAX_APP_SIZE (160*1024 - RESERVED_SIZE)
5332
5333 /* Header is 14 bytes */
5334 #define HEADER_SIZE 14
5335 #define DATA_OFFSET HEADER_SIZE
5336
5337 #define SPI_START_TRANSFER(bp, port, ext_phy_addr) \
5338         bnx2x_cl45_write(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, \
5339                         ext_phy_addr, \
5340                         MDIO_PCS_DEVAD, \
5341                         MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 1)
5342
5343 /* Programs an image to DSP's flash via the SPI port*/
5344 static u8 bnx2x_sfx7101_flash_download(struct bnx2x *bp, u8 port,
5345                                      u8 ext_phy_addr,
5346                                      char data[], u32 size)
5347 {
5348         const u16 num_trans = size/4; /* 4 bytes can be sent at a time */
5349         /* Doesn't include last trans!*/
5350         const u16 last_trans_size = size%4; /* Num bytes on last trans */
5351         u16 trans_cnt, byte_cnt;
5352         u32 data_index;
5353         u16 tmp;
5354         u16 code_started = 0;
5355         u16 image_revision1, image_revision2;
5356         u16 cnt;
5357
5358         DP(NETIF_MSG_LINK, "bnx2x_sfx7101_flash_download file_size=%d\n", size);
5359         /* Going to flash*/
5360         if ((size-HEADER_SIZE) > MAX_APP_SIZE) {
5361                 /* This very often will be the case, because the image is built
5362                 with 160Kbytes size whereas the total image size must actually
5363                 be 160Kbytes-RESERVED_SIZE */
5364                 DP(NETIF_MSG_LINK, "Warning, file size was %d bytes "
5365                          "truncated to %d bytes\n", size, MAX_APP_SIZE);
5366                 size = MAX_APP_SIZE+HEADER_SIZE;
5367         }
5368         DP(NETIF_MSG_LINK, "File version is %c%c\n", data[0x14e], data[0x14f]);
5369         DP(NETIF_MSG_LINK, "          %c%c\n", data[0x150], data[0x151]);
5370         /* Put the DSP in download mode by setting FLASH_CFG[2] to 1
5371            and issuing a reset.*/
5372
5373         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
5374                           MISC_REGISTERS_GPIO_HIGH, port);
5375
5376         bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
5377
5378         /* wait 0.5 sec */
5379         for (cnt = 0; cnt < 100; cnt++)
5380                 msleep(5);
5381
5382         /* Make sure we can access the DSP
5383            And it's in the correct mode (waiting for download) */
5384
5385         bnx2x_cl45_read(bp, port,
5386                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5387                       ext_phy_addr,
5388                       MDIO_PCS_DEVAD,
5389                       MDIO_PCS_REG_7101_DSP_ACCESS, &tmp);
5390
5391         if (tmp != 0x000A) {
5392                 DP(NETIF_MSG_LINK, "DSP is not in waiting on download mode. "
5393                          "Expected 0x000A, read 0x%04X\n", tmp);
5394                 DP(NETIF_MSG_LINK, "Download failed\n");
5395                 return -EINVAL;
5396         }
5397
5398         /* Mux the SPI interface away from the internal processor */
5399         bnx2x_cl45_write(bp, port,
5400                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5401                        ext_phy_addr,
5402                        MDIO_PCS_DEVAD,
5403                        MDIO_PCS_REG_7101_SPI_MUX, 1);
5404
5405         /* Reset the SPI port */
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, 0);
5411         bnx2x_cl45_write(bp, port,
5412                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5413                        ext_phy_addr,
5414                        MDIO_PCS_DEVAD,
5415                        MDIO_PCS_REG_7101_SPI_CTRL_ADDR,
5416                        (1<<MDIO_PCS_REG_7101_SPI_RESET_BIT));
5417         bnx2x_cl45_write(bp, port,
5418                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5419                        ext_phy_addr,
5420                        MDIO_PCS_DEVAD,
5421                        MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
5422
5423         /* Erase the flash */
5424         bnx2x_cl45_write(bp, port,
5425                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5426                        ext_phy_addr,
5427                        MDIO_PCS_DEVAD,
5428                        MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5429                        MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
5430
5431         bnx2x_cl45_write(bp, port,
5432                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5433                        ext_phy_addr,
5434                        MDIO_PCS_DEVAD,
5435                        MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5436                        1);
5437
5438         SPI_START_TRANSFER(bp, port, ext_phy_addr);
5439         bnx2x_cl45_write(bp, port,
5440                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5441                        ext_phy_addr,
5442                        MDIO_PCS_DEVAD,
5443                        MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5444                        MDIO_PCS_REG_7101_SPI_FIFO_ADDR_BULK_ERASE_CMD);
5445
5446         bnx2x_cl45_write(bp, port,
5447                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5448                        ext_phy_addr,
5449                        MDIO_PCS_DEVAD,
5450                        MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5451                        1);
5452         SPI_START_TRANSFER(bp, port, ext_phy_addr);
5453
5454         /* Wait 10 seconds, the maximum time for the erase to complete */
5455         DP(NETIF_MSG_LINK, "Erasing flash, this takes 10 seconds...\n");
5456         for (cnt = 0; cnt < 1000; cnt++)
5457                 msleep(10);
5458
5459         DP(NETIF_MSG_LINK, "Downloading flash, please wait...\n");
5460         data_index = 0;
5461         for (trans_cnt = 0; trans_cnt < num_trans; trans_cnt++) {
5462                 bnx2x_cl45_write(bp, port,
5463                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5464                              ext_phy_addr,
5465                              MDIO_PCS_DEVAD,
5466                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5467                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
5468
5469                 bnx2x_cl45_write(bp, port,
5470                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5471                                ext_phy_addr,
5472                                MDIO_PCS_DEVAD,
5473                                MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5474                                1);
5475                 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5476
5477                 bnx2x_cl45_write(bp, port,
5478                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5479                                ext_phy_addr,
5480                                MDIO_PCS_DEVAD,
5481                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5482                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
5483
5484                 /* Bits 23-16 of address */
5485                 bnx2x_cl45_write(bp, port,
5486                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5487                                ext_phy_addr,
5488                                MDIO_PCS_DEVAD,
5489                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5490                                (data_index>>16));
5491                 /* Bits 15-8 of address */
5492                 bnx2x_cl45_write(bp, port,
5493                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5494                                ext_phy_addr,
5495                                MDIO_PCS_DEVAD,
5496                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5497                                (data_index>>8));
5498
5499                 /* Bits 7-0 of address */
5500                 bnx2x_cl45_write(bp, port,
5501                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5502                                ext_phy_addr,
5503                                MDIO_PCS_DEVAD,
5504                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5505                                ((u16)data_index));
5506
5507                 byte_cnt = 0;
5508                 while (byte_cnt < 4 && data_index < size) {
5509                         bnx2x_cl45_write(bp, port,
5510                                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5511                                        ext_phy_addr,
5512                                MDIO_PCS_DEVAD,
5513                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5514                                data[data_index++]);
5515                         byte_cnt++;
5516                 }
5517
5518                 bnx2x_cl45_write(bp, port,
5519                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5520                                ext_phy_addr,
5521                                MDIO_PCS_DEVAD,
5522                                MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5523                                byte_cnt+4);
5524
5525                 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5526                 msleep(5); /* Wait 5 ms minimum between transs */
5527
5528                 /* Let the user know something's going on.*/
5529                 /* a pacifier ever 4K */
5530                 if ((data_index % 1023) == 0)
5531                         DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
5532         }
5533
5534         DP(NETIF_MSG_LINK, "\n");
5535         /* Transfer the last block if there is data remaining */
5536         if (last_trans_size) {
5537                 bnx2x_cl45_write(bp, port,
5538                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5539                         ext_phy_addr,
5540                         MDIO_PCS_DEVAD,
5541                         MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5542                         MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
5543
5544                 bnx2x_cl45_write(bp, port,
5545                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5546                                ext_phy_addr,
5547                                MDIO_PCS_DEVAD,
5548                                MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5549                                1);
5550
5551                 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5552
5553                 bnx2x_cl45_write(bp, port,
5554                              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5555                              ext_phy_addr,
5556                              MDIO_PCS_DEVAD,
5557                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5558                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
5559
5560                 /* Bits 23-16 of address */
5561                 bnx2x_cl45_write(bp, port,
5562                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5563                                ext_phy_addr,
5564                                MDIO_PCS_DEVAD,
5565                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5566                                (data_index>>16));
5567                 /* Bits 15-8 of address */
5568                 bnx2x_cl45_write(bp, port,
5569                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5570                                ext_phy_addr,
5571                                MDIO_PCS_DEVAD,
5572                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5573                                (data_index>>8));
5574
5575                 /* Bits 7-0 of address */
5576                 bnx2x_cl45_write(bp, port,
5577                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5578                                ext_phy_addr,
5579                                MDIO_PCS_DEVAD,
5580                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5581                                ((u16)data_index));
5582
5583                 byte_cnt = 0;
5584                 while (byte_cnt < last_trans_size && data_index < size) {
5585                         /* Bits 7-0 of address */
5586                         bnx2x_cl45_write(bp, port,
5587                                 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5588                                 ext_phy_addr,
5589                                 MDIO_PCS_DEVAD,
5590                                 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5591                                 data[data_index++]);
5592                         byte_cnt++;
5593                 }
5594
5595                 bnx2x_cl45_write(bp, port,
5596                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5597                                ext_phy_addr,
5598                                MDIO_PCS_DEVAD,
5599                                MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5600                                byte_cnt+4);
5601
5602                 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5603         }
5604
5605         /* DSP Remove Download Mode */
5606         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
5607                           MISC_REGISTERS_GPIO_LOW, port);
5608
5609         bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
5610
5611         /* wait 0.5 sec to allow it to run */
5612         for (cnt = 0; cnt < 100; cnt++)
5613                 msleep(5);
5614
5615         bnx2x_hw_reset(bp, port);
5616
5617         for (cnt = 0; cnt < 100; cnt++)
5618                 msleep(5);
5619
5620         /* Check that the code is started. In case the download
5621         checksum failed, the code won't be started. */
5622         bnx2x_cl45_read(bp, port,
5623                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5624                       ext_phy_addr,
5625                       MDIO_PCS_DEVAD,
5626                       MDIO_PCS_REG_7101_DSP_ACCESS,
5627                       &tmp);
5628
5629         code_started = (tmp & (1<<4));
5630         if (!code_started) {
5631                 DP(NETIF_MSG_LINK, "Download failed. Please check file.\n");
5632                 return -EINVAL;
5633         }
5634
5635         /* Verify that the file revision is now equal to the image
5636         revision within the DSP */
5637         bnx2x_cl45_read(bp, port,
5638                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5639                       ext_phy_addr,
5640                       MDIO_PMA_DEVAD,
5641                       MDIO_PMA_REG_7101_VER1,
5642                       &image_revision1);
5643
5644         bnx2x_cl45_read(bp, port,
5645                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5646                       ext_phy_addr,
5647                       MDIO_PMA_DEVAD,
5648                       MDIO_PMA_REG_7101_VER2,
5649                       &image_revision2);
5650
5651         if (data[0x14e] != (image_revision2&0xFF) ||
5652             data[0x14f] != ((image_revision2&0xFF00)>>8) ||
5653             data[0x150] != (image_revision1&0xFF) ||
5654             data[0x151] != ((image_revision1&0xFF00)>>8)) {
5655                 DP(NETIF_MSG_LINK, "Download failed.\n");
5656                 return -EINVAL;
5657         }
5658         DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
5659         return 0;
5660 }
5661
5662 u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
5663                       u8 driver_loaded, char data[], u32 size)
5664 {
5665         u8 rc = 0;
5666         u32 ext_phy_type;
5667         u8 ext_phy_addr;
5668         ext_phy_addr = ((ext_phy_config &
5669                         PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
5670                         PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
5671
5672         ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
5673
5674         switch (ext_phy_type) {
5675         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
5676         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
5677         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
5678         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
5679                 DP(NETIF_MSG_LINK,
5680                         "Flash download not supported for this ext phy\n");
5681                 rc = -EINVAL;
5682                 break;
5683         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
5684                 /* Take ext phy out of reset */
5685                 if (!driver_loaded)
5686                         bnx2x_turn_on_ef(bp, port, ext_phy_addr, ext_phy_type);
5687                 rc = bnx2x_sfx7101_flash_download(bp, port, ext_phy_addr,
5688                                                 data, size);
5689                 if (!driver_loaded)
5690                         bnx2x_turn_off_sf(bp, port);
5691                 break;
5692         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
5693         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
5694         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
5695         default:
5696                 DP(NETIF_MSG_LINK, "Invalid ext phy type\n");
5697                 rc = -EINVAL;
5698                 break;
5699         }
5700         return rc;
5701 }
5702