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