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