wireless, wavelan: spin off by 1
[linux-2.6] / drivers / net / bnx2x_link.c
1 /* Copyright 2008-2009 Broadcom Corporation
2  *
3  * Unless you and Broadcom execute a separate written software license
4  * agreement governing use of this software, this software is licensed to you
5  * under the terms of the GNU General Public License version 2, available
6  * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL").
7  *
8  * Notwithstanding the above, under no circumstances may you combine this
9  * software in any way with any other Broadcom software provided under a
10  * license other than the GPL, without Broadcom's express prior written
11  * consent.
12  *
13  * Written by Yaniv Rosner
14  *
15  */
16
17 #include <linux/kernel.h>
18 #include <linux/errno.h>
19 #include <linux/pci.h>
20 #include <linux/netdevice.h>
21 #include <linux/delay.h>
22 #include <linux/ethtool.h>
23 #include <linux/mutex.h>
24
25 #include "bnx2x.h"
26
27 /********************************************************/
28 #define ETH_HLEN                        14
29 #define ETH_OVREHEAD            (ETH_HLEN + 8)/* 8 for CRC + VLAN*/
30 #define ETH_MIN_PACKET_SIZE             60
31 #define ETH_MAX_PACKET_SIZE             1500
32 #define ETH_MAX_JUMBO_PACKET_SIZE       9600
33 #define MDIO_ACCESS_TIMEOUT             1000
34 #define BMAC_CONTROL_RX_ENABLE  2
35
36 /***********************************************************/
37 /*                      Shortcut definitions               */
38 /***********************************************************/
39
40 #define NIG_STATUS_XGXS0_LINK10G \
41                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
42 #define NIG_STATUS_XGXS0_LINK_STATUS \
43                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
44 #define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
45                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
46 #define NIG_STATUS_SERDES0_LINK_STATUS \
47                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
48 #define NIG_MASK_MI_INT \
49                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
50 #define NIG_MASK_XGXS0_LINK10G \
51                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
52 #define NIG_MASK_XGXS0_LINK_STATUS \
53                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
54 #define NIG_MASK_SERDES0_LINK_STATUS \
55                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
56
57 #define MDIO_AN_CL73_OR_37_COMPLETE \
58                 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
59                  MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
60
61 #define XGXS_RESET_BITS \
62         (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW |   \
63          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ |      \
64          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN |    \
65          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
66          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
67
68 #define SERDES_RESET_BITS \
69         (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
70          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ |    \
71          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN |  \
72          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
73
74 #define AUTONEG_CL37            SHARED_HW_CFG_AN_ENABLE_CL37
75 #define AUTONEG_CL73            SHARED_HW_CFG_AN_ENABLE_CL73
76 #define AUTONEG_BAM             SHARED_HW_CFG_AN_ENABLE_BAM
77 #define AUTONEG_PARALLEL \
78                                 SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
79 #define AUTONEG_SGMII_FIBER_AUTODET \
80                                 SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
81 #define AUTONEG_REMOTE_PHY      SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
82
83 #define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
84                         MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
85 #define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
86                         MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
87 #define GP_STATUS_SPEED_MASK \
88                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
89 #define GP_STATUS_10M   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
90 #define GP_STATUS_100M  MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
91 #define GP_STATUS_1G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
92 #define GP_STATUS_2_5G  MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
93 #define GP_STATUS_5G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
94 #define GP_STATUS_6G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
95 #define GP_STATUS_10G_HIG \
96                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
97 #define GP_STATUS_10G_CX4 \
98                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
99 #define GP_STATUS_12G_HIG \
100                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG
101 #define GP_STATUS_12_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G
102 #define GP_STATUS_13G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G
103 #define GP_STATUS_15G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G
104 #define GP_STATUS_16G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G
105 #define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
106 #define GP_STATUS_10G_KX4 \
107                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
108
109 #define LINK_10THD                      LINK_STATUS_SPEED_AND_DUPLEX_10THD
110 #define LINK_10TFD                      LINK_STATUS_SPEED_AND_DUPLEX_10TFD
111 #define LINK_100TXHD            LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
112 #define LINK_100T4                      LINK_STATUS_SPEED_AND_DUPLEX_100T4
113 #define LINK_100TXFD            LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
114 #define LINK_1000THD            LINK_STATUS_SPEED_AND_DUPLEX_1000THD
115 #define LINK_1000TFD            LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
116 #define LINK_1000XFD            LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
117 #define LINK_2500THD            LINK_STATUS_SPEED_AND_DUPLEX_2500THD
118 #define LINK_2500TFD            LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
119 #define LINK_2500XFD            LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
120 #define LINK_10GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
121 #define LINK_10GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
122 #define LINK_12GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_12GTFD
123 #define LINK_12GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_12GXFD
124 #define LINK_12_5GTFD           LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD
125 #define LINK_12_5GXFD           LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD
126 #define LINK_13GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_13GTFD
127 #define LINK_13GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_13GXFD
128 #define LINK_15GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_15GTFD
129 #define LINK_15GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_15GXFD
130 #define LINK_16GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_16GTFD
131 #define LINK_16GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_16GXFD
132
133 #define PHY_XGXS_FLAG                   0x1
134 #define PHY_SGMII_FLAG                  0x2
135 #define PHY_SERDES_FLAG                 0x4
136
137 /* */
138 #define SFP_EEPROM_CON_TYPE_ADDR                0x2
139         #define SFP_EEPROM_CON_TYPE_VAL_LC              0x7
140         #define SFP_EEPROM_CON_TYPE_VAL_COPPER  0x21
141
142 #define SFP_EEPROM_FC_TX_TECH_ADDR              0x8
143         #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
144         #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE      0x8
145 #define SFP_EEPROM_VENDOR_NAME_ADDR             0x14
146 #define SFP_EEPROM_VENDOR_NAME_SIZE     16
147 #define SFP_EEPROM_OPTIONS_ADDR                 0x40
148         #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
149 #define SFP_EEPROM_OPTIONS_SIZE                 2
150
151 #define SFP_MODULE_TYPE_UNKNOWN                         0x0
152 #define SFP_MODULE_TYPE_LC                      0x1
153 #define SFP_MODULE_TYPE_ACTIVE_COPPER_CABLE             0x2
154 #define SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE    0x3
155
156 #define SFP_LIMITING_MODE_VALUE                         0x0044
157 /**********************************************************/
158 /*                     INTERFACE                          */
159 /**********************************************************/
160 #define CL45_WR_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
161         bnx2x_cl45_write(_bp, _port, 0, _phy_addr, \
162                 DEFAULT_PHY_DEV_ADDR, \
163                 (_bank + (_addr & 0xf)), \
164                 _val)
165
166 #define CL45_RD_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
167         bnx2x_cl45_read(_bp, _port, 0, _phy_addr, \
168                 DEFAULT_PHY_DEV_ADDR, \
169                 (_bank + (_addr & 0xf)), \
170                 _val)
171
172 static void bnx2x_set_serdes_access(struct link_params *params)
173 {
174         struct bnx2x *bp = params->bp;
175         u32 emac_base = (params->port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
176         /* Set Clause 22 */
177         REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + params->port*0x10, 1);
178         REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
179         udelay(500);
180         REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
181         udelay(500);
182          /* Set Clause 45 */
183         REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + params->port*0x10, 0);
184 }
185 static void bnx2x_set_phy_mdio(struct link_params *params, u8 phy_flags)
186 {
187         struct bnx2x *bp = params->bp;
188         if (phy_flags & PHY_XGXS_FLAG) {
189                 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
190                            params->port*0x18, 0);
191                 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
192                            DEFAULT_PHY_DEV_ADDR);
193         } else {
194                 bnx2x_set_serdes_access(params);
195
196                 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD +
197                            params->port*0x10,
198                            DEFAULT_PHY_DEV_ADDR);
199         }
200 }
201
202 static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
203 {
204         u32 val = REG_RD(bp, reg);
205
206         val |= bits;
207         REG_WR(bp, reg, val);
208         return val;
209 }
210
211 static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
212 {
213         u32 val = REG_RD(bp, reg);
214
215         val &= ~bits;
216         REG_WR(bp, reg, val);
217         return val;
218 }
219
220 static void bnx2x_emac_init(struct link_params *params,
221                            struct link_vars *vars)
222 {
223         /* reset and unreset the emac core */
224         struct bnx2x *bp = params->bp;
225         u8 port = params->port;
226         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
227         u32 val;
228         u16 timeout;
229
230         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
231                    (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
232         udelay(5);
233         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
234                    (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
235
236         /* init emac - use read-modify-write */
237         /* self clear reset */
238         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
239         EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
240
241         timeout = 200;
242         do {
243                 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
244                 DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
245                 if (!timeout) {
246                         DP(NETIF_MSG_LINK, "EMAC timeout!\n");
247                         return;
248                 }
249                 timeout--;
250         } while (val & EMAC_MODE_RESET);
251
252         /* Set mac address */
253         val = ((params->mac_addr[0] << 8) |
254                 params->mac_addr[1]);
255         EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH, val);
256
257         val = ((params->mac_addr[2] << 24) |
258                (params->mac_addr[3] << 16) |
259                (params->mac_addr[4] << 8) |
260                 params->mac_addr[5]);
261         EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val);
262 }
263
264 static u8 bnx2x_emac_enable(struct link_params *params,
265                           struct link_vars *vars, u8 lb)
266 {
267         struct bnx2x *bp = params->bp;
268         u8 port = params->port;
269         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
270         u32 val;
271
272         DP(NETIF_MSG_LINK, "enabling EMAC\n");
273
274         /* enable emac and not bmac */
275         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
276
277         /* for paladium */
278         if (CHIP_REV_IS_EMUL(bp)) {
279                 /* Use lane 1 (of lanes 0-3) */
280                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
281                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
282                             port*4, 1);
283         }
284         /* for fpga */
285         else
286
287         if (CHIP_REV_IS_FPGA(bp)) {
288                 /* Use lane 1 (of lanes 0-3) */
289                 DP(NETIF_MSG_LINK, "bnx2x_emac_enable: Setting FPGA\n");
290
291                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
292                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4,
293                             0);
294         } else
295         /* ASIC */
296         if (vars->phy_flags & PHY_XGXS_FLAG) {
297                 u32 ser_lane = ((params->lane_config &
298                             PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
299                             PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
300
301                 DP(NETIF_MSG_LINK, "XGXS\n");
302                 /* select the master lanes (out of 0-3) */
303                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 +
304                            port*4, ser_lane);
305                 /* select XGXS */
306                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
307                            port*4, 1);
308
309         } else { /* SerDes */
310                 DP(NETIF_MSG_LINK, "SerDes\n");
311                 /* select SerDes */
312                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
313                            port*4, 0);
314         }
315
316         bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
317                     EMAC_RX_MODE_RESET);
318         bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
319                     EMAC_TX_MODE_RESET);
320
321         if (CHIP_REV_IS_SLOW(bp)) {
322                 /* config GMII mode */
323                 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
324                 EMAC_WR(bp, EMAC_REG_EMAC_MODE,
325                             (val | EMAC_MODE_PORT_GMII));
326         } else { /* ASIC */
327                 /* pause enable/disable */
328                 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
329                                EMAC_RX_MODE_FLOW_EN);
330                 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
331                         bnx2x_bits_en(bp, emac_base +
332                                     EMAC_REG_EMAC_RX_MODE,
333                                     EMAC_RX_MODE_FLOW_EN);
334
335                 bnx2x_bits_dis(bp,  emac_base + EMAC_REG_EMAC_TX_MODE,
336                              (EMAC_TX_MODE_EXT_PAUSE_EN |
337                               EMAC_TX_MODE_FLOW_EN));
338                 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
339                         bnx2x_bits_en(bp, emac_base +
340                                     EMAC_REG_EMAC_TX_MODE,
341                                    (EMAC_TX_MODE_EXT_PAUSE_EN |
342                                     EMAC_TX_MODE_FLOW_EN));
343         }
344
345         /* KEEP_VLAN_TAG, promiscuous */
346         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
347         val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
348         EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
349
350         /* Set Loopback */
351         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
352         if (lb)
353                 val |= 0x810;
354         else
355                 val &= ~0x810;
356         EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
357
358         /* enable emac */
359         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
360
361         /* enable emac for jumbo packets */
362         EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
363                 (EMAC_RX_MTU_SIZE_JUMBO_ENA |
364                  (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
365
366         /* strip CRC */
367         REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
368
369         /* disable the NIG in/out to the bmac */
370         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
371         REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
372         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
373
374         /* enable the NIG in/out to the emac */
375         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
376         val = 0;
377         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
378                 val = 1;
379
380         REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
381         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
382
383         if (CHIP_REV_IS_EMUL(bp)) {
384                 /* take the BigMac out of reset */
385                 REG_WR(bp,
386                            GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
387                            (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
388
389                 /* enable access for bmac registers */
390                 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
391         }
392
393         vars->mac_type = MAC_TYPE_EMAC;
394         return 0;
395 }
396
397
398
399 static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
400                           u8 is_lb)
401 {
402         struct bnx2x *bp = params->bp;
403         u8 port = params->port;
404         u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
405                                NIG_REG_INGRESS_BMAC0_MEM;
406         u32 wb_data[2];
407         u32 val;
408
409         DP(NETIF_MSG_LINK, "Enabling BigMAC\n");
410         /* reset and unreset the BigMac */
411         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
412                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
413         msleep(1);
414
415         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
416                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
417
418         /* enable access for bmac registers */
419         REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
420
421         /* XGXS control */
422         wb_data[0] = 0x3c;
423         wb_data[1] = 0;
424         REG_WR_DMAE(bp, bmac_addr +
425                       BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
426                       wb_data, 2);
427
428         /* tx MAC SA */
429         wb_data[0] = ((params->mac_addr[2] << 24) |
430                        (params->mac_addr[3] << 16) |
431                        (params->mac_addr[4] << 8) |
432                         params->mac_addr[5]);
433         wb_data[1] = ((params->mac_addr[0] << 8) |
434                         params->mac_addr[1]);
435         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR,
436                     wb_data, 2);
437
438         /* tx control */
439         val = 0xc0;
440         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
441                 val |= 0x800000;
442         wb_data[0] = val;
443         wb_data[1] = 0;
444         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL,
445                         wb_data, 2);
446
447         /* mac control */
448         val = 0x3;
449         if (is_lb) {
450                 val |= 0x4;
451                 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
452         }
453         wb_data[0] = val;
454         wb_data[1] = 0;
455         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
456                     wb_data, 2);
457
458
459         /* set rx mtu */
460         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
461         wb_data[1] = 0;
462         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE,
463                         wb_data, 2);
464
465         /* rx control set to don't strip crc */
466         val = 0x14;
467         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
468                 val |= 0x20;
469         wb_data[0] = val;
470         wb_data[1] = 0;
471         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL,
472                         wb_data, 2);
473
474         /* set tx mtu */
475         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
476         wb_data[1] = 0;
477         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE,
478                         wb_data, 2);
479
480         /* set cnt max size */
481         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
482         wb_data[1] = 0;
483         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE,
484                     wb_data, 2);
485
486         /* configure safc */
487         wb_data[0] = 0x1000200;
488         wb_data[1] = 0;
489         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
490                     wb_data, 2);
491         /* fix for emulation */
492         if (CHIP_REV_IS_EMUL(bp)) {
493                 wb_data[0] = 0xf000;
494                 wb_data[1] = 0;
495                 REG_WR_DMAE(bp,
496                             bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
497                             wb_data, 2);
498         }
499
500         REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
501         REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
502         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
503         val = 0;
504         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
505                 val = 1;
506         REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
507         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
508         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
509         REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
510         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
511         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
512
513         vars->mac_type = MAC_TYPE_BMAC;
514         return 0;
515 }
516
517 static void bnx2x_phy_deassert(struct link_params *params, u8 phy_flags)
518 {
519         struct bnx2x *bp = params->bp;
520         u32 val;
521
522         if (phy_flags & PHY_XGXS_FLAG) {
523                 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:XGXS\n");
524                 val = XGXS_RESET_BITS;
525
526         } else { /* SerDes */
527                 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:SerDes\n");
528                 val = SERDES_RESET_BITS;
529         }
530
531         val = val << (params->port*16);
532
533         /* reset and unreset the SerDes/XGXS */
534         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
535                     val);
536         udelay(500);
537         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET,
538                     val);
539         bnx2x_set_phy_mdio(params, phy_flags);
540 }
541
542 void bnx2x_link_status_update(struct link_params *params,
543                             struct link_vars   *vars)
544 {
545         struct bnx2x *bp = params->bp;
546         u8 link_10g;
547         u8 port = params->port;
548
549         if (params->switch_cfg ==  SWITCH_CFG_1G)
550                 vars->phy_flags = PHY_SERDES_FLAG;
551         else
552                 vars->phy_flags = PHY_XGXS_FLAG;
553         vars->link_status = REG_RD(bp, params->shmem_base +
554                                           offsetof(struct shmem_region,
555                                            port_mb[port].link_status));
556
557         vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
558
559         if (vars->link_up) {
560                 DP(NETIF_MSG_LINK, "phy link up\n");
561
562                 vars->phy_link_up = 1;
563                 vars->duplex = DUPLEX_FULL;
564                 switch (vars->link_status &
565                                         LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
566                         case LINK_10THD:
567                                 vars->duplex = DUPLEX_HALF;
568                                 /* fall thru */
569                         case LINK_10TFD:
570                                 vars->line_speed = SPEED_10;
571                                 break;
572
573                         case LINK_100TXHD:
574                                 vars->duplex = DUPLEX_HALF;
575                                 /* fall thru */
576                         case LINK_100T4:
577                         case LINK_100TXFD:
578                                 vars->line_speed = SPEED_100;
579                                 break;
580
581                         case LINK_1000THD:
582                                 vars->duplex = DUPLEX_HALF;
583                                 /* fall thru */
584                         case LINK_1000TFD:
585                                 vars->line_speed = SPEED_1000;
586                                 break;
587
588                         case LINK_2500THD:
589                                 vars->duplex = DUPLEX_HALF;
590                                 /* fall thru */
591                         case LINK_2500TFD:
592                                 vars->line_speed = SPEED_2500;
593                                 break;
594
595                         case LINK_10GTFD:
596                                 vars->line_speed = SPEED_10000;
597                                 break;
598
599                         case LINK_12GTFD:
600                                 vars->line_speed = SPEED_12000;
601                                 break;
602
603                         case LINK_12_5GTFD:
604                                 vars->line_speed = SPEED_12500;
605                                 break;
606
607                         case LINK_13GTFD:
608                                 vars->line_speed = SPEED_13000;
609                                 break;
610
611                         case LINK_15GTFD:
612                                 vars->line_speed = SPEED_15000;
613                                 break;
614
615                         case LINK_16GTFD:
616                                 vars->line_speed = SPEED_16000;
617                                 break;
618
619                         default:
620                                 break;
621                 }
622
623                 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
624                         vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
625                 else
626                         vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_TX;
627
628                 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
629                         vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
630                 else
631                         vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_RX;
632
633                 if (vars->phy_flags & PHY_XGXS_FLAG) {
634                         if (vars->line_speed &&
635                             ((vars->line_speed == SPEED_10) ||
636                              (vars->line_speed == SPEED_100))) {
637                                 vars->phy_flags |= PHY_SGMII_FLAG;
638                         } else {
639                                 vars->phy_flags &= ~PHY_SGMII_FLAG;
640                         }
641                 }
642
643                 /* anything 10 and over uses the bmac */
644                 link_10g = ((vars->line_speed == SPEED_10000) ||
645                             (vars->line_speed == SPEED_12000) ||
646                             (vars->line_speed == SPEED_12500) ||
647                             (vars->line_speed == SPEED_13000) ||
648                             (vars->line_speed == SPEED_15000) ||
649                             (vars->line_speed == SPEED_16000));
650                 if (link_10g)
651                         vars->mac_type = MAC_TYPE_BMAC;
652                 else
653                         vars->mac_type = MAC_TYPE_EMAC;
654
655         } else { /* link down */
656                 DP(NETIF_MSG_LINK, "phy link down\n");
657
658                 vars->phy_link_up = 0;
659
660                 vars->line_speed = 0;
661                 vars->duplex = DUPLEX_FULL;
662                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
663
664                 /* indicate no mac active */
665                 vars->mac_type = MAC_TYPE_NONE;
666         }
667
668         DP(NETIF_MSG_LINK, "link_status 0x%x  phy_link_up %x\n",
669                  vars->link_status, vars->phy_link_up);
670         DP(NETIF_MSG_LINK, "line_speed %x  duplex %x  flow_ctrl 0x%x\n",
671                  vars->line_speed, vars->duplex, vars->flow_ctrl);
672 }
673
674 static void bnx2x_update_mng(struct link_params *params, u32 link_status)
675 {
676         struct bnx2x *bp = params->bp;
677         REG_WR(bp, params->shmem_base +
678                    offsetof(struct shmem_region,
679                             port_mb[params->port].link_status),
680                         link_status);
681 }
682
683 static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
684 {
685         u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
686                 NIG_REG_INGRESS_BMAC0_MEM;
687         u32 wb_data[2];
688         u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
689
690         /* Only if the bmac is out of reset */
691         if (REG_RD(bp, MISC_REG_RESET_REG_2) &
692                         (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
693             nig_bmac_enable) {
694
695                 /* Clear Rx Enable bit in BMAC_CONTROL register */
696                 REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
697                             wb_data, 2);
698                 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
699                 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
700                             wb_data, 2);
701
702                 msleep(1);
703         }
704 }
705
706 static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
707                          u32 line_speed)
708 {
709         struct bnx2x *bp = params->bp;
710         u8 port = params->port;
711         u32 init_crd, crd;
712         u32 count = 1000;
713
714         /* disable port */
715         REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
716
717         /* wait for init credit */
718         init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
719         crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
720         DP(NETIF_MSG_LINK, "init_crd 0x%x  crd 0x%x\n", init_crd, crd);
721
722         while ((init_crd != crd) && count) {
723                 msleep(5);
724
725                 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
726                 count--;
727         }
728         crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
729         if (init_crd != crd) {
730                 DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
731                           init_crd, crd);
732                 return -EINVAL;
733         }
734
735         if (flow_ctrl & BNX2X_FLOW_CTRL_RX ||
736             line_speed == SPEED_10 ||
737             line_speed == SPEED_100 ||
738             line_speed == SPEED_1000 ||
739             line_speed == SPEED_2500) {
740                 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
741                 /* update threshold */
742                 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
743                 /* update init credit */
744                 init_crd = 778;         /* (800-18-4) */
745
746         } else {
747                 u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
748                               ETH_OVREHEAD)/16;
749                 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
750                 /* update threshold */
751                 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
752                 /* update init credit */
753                 switch (line_speed) {
754                 case SPEED_10000:
755                         init_crd = thresh + 553 - 22;
756                         break;
757
758                 case SPEED_12000:
759                         init_crd = thresh + 664 - 22;
760                         break;
761
762                 case SPEED_13000:
763                         init_crd = thresh + 742 - 22;
764                         break;
765
766                 case SPEED_16000:
767                         init_crd = thresh + 778 - 22;
768                         break;
769                 default:
770                         DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
771                                   line_speed);
772                         return -EINVAL;
773                         break;
774                 }
775         }
776         REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
777         DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
778                  line_speed, init_crd);
779
780         /* probe the credit changes */
781         REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
782         msleep(5);
783         REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
784
785         /* enable port */
786         REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
787         return 0;
788 }
789
790 static u32 bnx2x_get_emac_base(struct bnx2x *bp, u32 ext_phy_type, u8 port)
791 {
792         u32 emac_base;
793         switch (ext_phy_type) {
794         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
795         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
796                 /* All MDC/MDIO is directed through single EMAC */
797                 if (REG_RD(bp, NIG_REG_PORT_SWAP))
798                         emac_base = GRCBASE_EMAC0;
799                 else
800                         emac_base = GRCBASE_EMAC1;
801                 break;
802         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
803                 emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
804                 break;
805         default:
806                 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
807                 break;
808         }
809         return emac_base;
810
811 }
812
813 u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
814                   u8 phy_addr, u8 devad, u16 reg, u16 val)
815 {
816         u32 tmp, saved_mode;
817         u8 i, rc = 0;
818         u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
819
820         /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
821          * (a value of 49==0x31) and make sure that the AUTO poll is off
822          */
823
824         saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
825         tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
826                              EMAC_MDIO_MODE_CLOCK_CNT);
827         tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
828                 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
829         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
830         REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
831         udelay(40);
832
833         /* address */
834
835         tmp = ((phy_addr << 21) | (devad << 16) | reg |
836                EMAC_MDIO_COMM_COMMAND_ADDRESS |
837                EMAC_MDIO_COMM_START_BUSY);
838         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
839
840         for (i = 0; i < 50; i++) {
841                 udelay(10);
842
843                 tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
844                 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
845                         udelay(5);
846                         break;
847                 }
848         }
849         if (tmp & EMAC_MDIO_COMM_START_BUSY) {
850                 DP(NETIF_MSG_LINK, "write phy register failed\n");
851                 rc = -EFAULT;
852         } else {
853                 /* data */
854                 tmp = ((phy_addr << 21) | (devad << 16) | val |
855                        EMAC_MDIO_COMM_COMMAND_WRITE_45 |
856                        EMAC_MDIO_COMM_START_BUSY);
857                 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
858
859                 for (i = 0; i < 50; i++) {
860                         udelay(10);
861
862                         tmp = REG_RD(bp, mdio_ctrl +
863                                          EMAC_REG_EMAC_MDIO_COMM);
864                         if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
865                                 udelay(5);
866                                 break;
867                         }
868                 }
869                 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
870                         DP(NETIF_MSG_LINK, "write phy register failed\n");
871                         rc = -EFAULT;
872                 }
873         }
874
875         /* Restore the saved mode */
876         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
877
878         return rc;
879 }
880
881 u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
882                  u8 phy_addr, u8 devad, u16 reg, u16 *ret_val)
883 {
884         u32 val, saved_mode;
885         u16 i;
886         u8 rc = 0;
887
888         u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
889         /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
890          * (a value of 49==0x31) and make sure that the AUTO poll is off
891          */
892
893         saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
894         val = saved_mode & ((EMAC_MDIO_MODE_AUTO_POLL |
895                              EMAC_MDIO_MODE_CLOCK_CNT));
896         val |= (EMAC_MDIO_MODE_CLAUSE_45 |
897                 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
898         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
899         REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
900         udelay(40);
901
902         /* address */
903         val = ((phy_addr << 21) | (devad << 16) | reg |
904                EMAC_MDIO_COMM_COMMAND_ADDRESS |
905                EMAC_MDIO_COMM_START_BUSY);
906         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
907
908         for (i = 0; i < 50; i++) {
909                 udelay(10);
910
911                 val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
912                 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
913                         udelay(5);
914                         break;
915                 }
916         }
917         if (val & EMAC_MDIO_COMM_START_BUSY) {
918                 DP(NETIF_MSG_LINK, "read phy register failed\n");
919
920                 *ret_val = 0;
921                 rc = -EFAULT;
922
923         } else {
924                 /* data */
925                 val = ((phy_addr << 21) | (devad << 16) |
926                        EMAC_MDIO_COMM_COMMAND_READ_45 |
927                        EMAC_MDIO_COMM_START_BUSY);
928                 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
929
930                 for (i = 0; i < 50; i++) {
931                         udelay(10);
932
933                         val = REG_RD(bp, mdio_ctrl +
934                                           EMAC_REG_EMAC_MDIO_COMM);
935                         if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
936                                 *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
937                                 break;
938                         }
939                 }
940                 if (val & EMAC_MDIO_COMM_START_BUSY) {
941                         DP(NETIF_MSG_LINK, "read phy register failed\n");
942
943                         *ret_val = 0;
944                         rc = -EFAULT;
945                 }
946         }
947
948         /* Restore the saved mode */
949         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
950
951         return rc;
952 }
953
954 static void bnx2x_set_aer_mmd(struct link_params *params,
955                             struct link_vars   *vars)
956 {
957         struct bnx2x *bp = params->bp;
958         u32 ser_lane;
959         u16 offset;
960
961         ser_lane = ((params->lane_config &
962                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
963                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
964
965         offset = (vars->phy_flags & PHY_XGXS_FLAG) ?
966                 (params->phy_addr + ser_lane) : 0;
967
968         CL45_WR_OVER_CL22(bp, params->port,
969                               params->phy_addr,
970                               MDIO_REG_BANK_AER_BLOCK,
971                               MDIO_AER_BLOCK_AER_REG, 0x3800 + offset);
972 }
973
974 static void bnx2x_set_master_ln(struct link_params *params)
975 {
976         struct bnx2x *bp = params->bp;
977         u16 new_master_ln, ser_lane;
978         ser_lane =  ((params->lane_config &
979                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
980                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
981
982         /* set the master_ln for AN */
983         CL45_RD_OVER_CL22(bp, params->port,
984                               params->phy_addr,
985                               MDIO_REG_BANK_XGXS_BLOCK2,
986                               MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
987                               &new_master_ln);
988
989         CL45_WR_OVER_CL22(bp, params->port,
990                               params->phy_addr,
991                               MDIO_REG_BANK_XGXS_BLOCK2 ,
992                               MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
993                               (new_master_ln | ser_lane));
994 }
995
996 static u8 bnx2x_reset_unicore(struct link_params *params)
997 {
998         struct bnx2x *bp = params->bp;
999         u16 mii_control;
1000         u16 i;
1001
1002         CL45_RD_OVER_CL22(bp, params->port,
1003                               params->phy_addr,
1004                               MDIO_REG_BANK_COMBO_IEEE0,
1005                               MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
1006
1007         /* reset the unicore */
1008         CL45_WR_OVER_CL22(bp, params->port,
1009                               params->phy_addr,
1010                               MDIO_REG_BANK_COMBO_IEEE0,
1011                               MDIO_COMBO_IEEE0_MII_CONTROL,
1012                               (mii_control |
1013                                MDIO_COMBO_IEEO_MII_CONTROL_RESET));
1014
1015         bnx2x_set_serdes_access(params);
1016
1017         /* wait for the reset to self clear */
1018         for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
1019                 udelay(5);
1020
1021                 /* the reset erased the previous bank value */
1022                 CL45_RD_OVER_CL22(bp, params->port,
1023                                       params->phy_addr,
1024                               MDIO_REG_BANK_COMBO_IEEE0,
1025                               MDIO_COMBO_IEEE0_MII_CONTROL,
1026                               &mii_control);
1027
1028                 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
1029                         udelay(5);
1030                         return 0;
1031                 }
1032         }
1033
1034         DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
1035         return -EINVAL;
1036
1037 }
1038
1039 static void bnx2x_set_swap_lanes(struct link_params *params)
1040 {
1041         struct bnx2x *bp = params->bp;
1042         /* Each two bits represents a lane number:
1043            No swap is 0123 => 0x1b no need to enable the swap */
1044         u16 ser_lane, rx_lane_swap, tx_lane_swap;
1045
1046         ser_lane = ((params->lane_config &
1047                          PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1048                         PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1049         rx_lane_swap = ((params->lane_config &
1050                              PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
1051                             PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
1052         tx_lane_swap = ((params->lane_config &
1053                              PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
1054                             PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
1055
1056         if (rx_lane_swap != 0x1b) {
1057                 CL45_WR_OVER_CL22(bp, params->port,
1058                                       params->phy_addr,
1059                                     MDIO_REG_BANK_XGXS_BLOCK2,
1060                                     MDIO_XGXS_BLOCK2_RX_LN_SWAP,
1061                                     (rx_lane_swap |
1062                                     MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
1063                                     MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
1064         } else {
1065                 CL45_WR_OVER_CL22(bp, params->port,
1066                                       params->phy_addr,
1067                                       MDIO_REG_BANK_XGXS_BLOCK2,
1068                                       MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
1069         }
1070
1071         if (tx_lane_swap != 0x1b) {
1072                 CL45_WR_OVER_CL22(bp, params->port,
1073                                       params->phy_addr,
1074                                       MDIO_REG_BANK_XGXS_BLOCK2,
1075                                       MDIO_XGXS_BLOCK2_TX_LN_SWAP,
1076                                       (tx_lane_swap |
1077                                        MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
1078         } else {
1079                 CL45_WR_OVER_CL22(bp, params->port,
1080                                       params->phy_addr,
1081                                       MDIO_REG_BANK_XGXS_BLOCK2,
1082                                       MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
1083         }
1084 }
1085
1086 static void bnx2x_set_parallel_detection(struct link_params *params,
1087                                        u8                phy_flags)
1088 {
1089         struct bnx2x *bp = params->bp;
1090         u16 control2;
1091
1092         CL45_RD_OVER_CL22(bp, params->port,
1093                               params->phy_addr,
1094                               MDIO_REG_BANK_SERDES_DIGITAL,
1095                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1096                               &control2);
1097
1098
1099         control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
1100
1101
1102         CL45_WR_OVER_CL22(bp, params->port,
1103                               params->phy_addr,
1104                               MDIO_REG_BANK_SERDES_DIGITAL,
1105                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1106                               control2);
1107
1108         if (phy_flags & PHY_XGXS_FLAG) {
1109                 DP(NETIF_MSG_LINK, "XGXS\n");
1110
1111                 CL45_WR_OVER_CL22(bp, params->port,
1112                                       params->phy_addr,
1113                                 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1114                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
1115                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
1116
1117                 CL45_RD_OVER_CL22(bp, params->port,
1118                                       params->phy_addr,
1119                                 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1120                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1121                                 &control2);
1122
1123
1124                 control2 |=
1125                     MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
1126
1127                 CL45_WR_OVER_CL22(bp, params->port,
1128                                       params->phy_addr,
1129                                 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1130                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1131                                 control2);
1132
1133                 /* Disable parallel detection of HiG */
1134                 CL45_WR_OVER_CL22(bp, params->port,
1135                                       params->phy_addr,
1136                                 MDIO_REG_BANK_XGXS_BLOCK2,
1137                                 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
1138                                 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
1139                                 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
1140         }
1141 }
1142
1143 static void bnx2x_set_autoneg(struct link_params *params,
1144                             struct link_vars   *vars)
1145 {
1146         struct bnx2x *bp = params->bp;
1147         u16 reg_val;
1148
1149         /* CL37 Autoneg */
1150
1151         CL45_RD_OVER_CL22(bp, params->port,
1152                               params->phy_addr,
1153                               MDIO_REG_BANK_COMBO_IEEE0,
1154                               MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
1155
1156         /* CL37 Autoneg Enabled */
1157         if (vars->line_speed == SPEED_AUTO_NEG)
1158                 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
1159         else /* CL37 Autoneg Disabled */
1160                 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1161                              MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
1162
1163         CL45_WR_OVER_CL22(bp, params->port,
1164                               params->phy_addr,
1165                               MDIO_REG_BANK_COMBO_IEEE0,
1166                               MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1167
1168         /* Enable/Disable Autodetection */
1169
1170         CL45_RD_OVER_CL22(bp, params->port,
1171                               params->phy_addr,
1172                               MDIO_REG_BANK_SERDES_DIGITAL,
1173                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
1174         reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN;
1175         if (vars->line_speed == SPEED_AUTO_NEG)
1176                 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1177         else
1178                 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1179
1180         CL45_WR_OVER_CL22(bp, params->port,
1181                               params->phy_addr,
1182                               MDIO_REG_BANK_SERDES_DIGITAL,
1183                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
1184
1185         /* Enable TetonII and BAM autoneg */
1186         CL45_RD_OVER_CL22(bp, params->port,
1187                               params->phy_addr,
1188                               MDIO_REG_BANK_BAM_NEXT_PAGE,
1189                               MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1190                           &reg_val);
1191         if (vars->line_speed == SPEED_AUTO_NEG) {
1192                 /* Enable BAM aneg Mode and TetonII aneg Mode */
1193                 reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1194                             MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1195         } else {
1196                 /* TetonII and BAM Autoneg Disabled */
1197                 reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1198                              MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1199         }
1200         CL45_WR_OVER_CL22(bp, params->port,
1201                               params->phy_addr,
1202                               MDIO_REG_BANK_BAM_NEXT_PAGE,
1203                               MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1204                               reg_val);
1205
1206         /* CL73 Autoneg Disabled */
1207         reg_val = 0;
1208
1209         CL45_WR_OVER_CL22(bp, params->port,
1210                               params->phy_addr,
1211                               MDIO_REG_BANK_CL73_IEEEB0,
1212                               MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
1213 }
1214
1215 /* program SerDes, forced speed */
1216 static void bnx2x_program_serdes(struct link_params *params,
1217                                struct link_vars *vars)
1218 {
1219         struct bnx2x *bp = params->bp;
1220         u16 reg_val;
1221
1222         /* program duplex, disable autoneg */
1223
1224         CL45_RD_OVER_CL22(bp, params->port,
1225                               params->phy_addr,
1226                               MDIO_REG_BANK_COMBO_IEEE0,
1227                               MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
1228         reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
1229                      MDIO_COMBO_IEEO_MII_CONTROL_AN_EN);
1230         if (params->req_duplex == DUPLEX_FULL)
1231                 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1232         CL45_WR_OVER_CL22(bp, params->port,
1233                               params->phy_addr,
1234                               MDIO_REG_BANK_COMBO_IEEE0,
1235                               MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1236
1237         /* program speed
1238            - needed only if the speed is greater than 1G (2.5G or 10G) */
1239         CL45_RD_OVER_CL22(bp, params->port,
1240                                       params->phy_addr,
1241                                       MDIO_REG_BANK_SERDES_DIGITAL,
1242                                       MDIO_SERDES_DIGITAL_MISC1, &reg_val);
1243         /* clearing the speed value before setting the right speed */
1244         DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
1245
1246         reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
1247                      MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1248
1249         if (!((vars->line_speed == SPEED_1000) ||
1250               (vars->line_speed == SPEED_100) ||
1251               (vars->line_speed == SPEED_10))) {
1252
1253                 reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
1254                             MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1255                 if (vars->line_speed == SPEED_10000)
1256                         reg_val |=
1257                                 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
1258                 if (vars->line_speed == SPEED_13000)
1259                         reg_val |=
1260                                 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G;
1261         }
1262
1263         CL45_WR_OVER_CL22(bp, params->port,
1264                                       params->phy_addr,
1265                                       MDIO_REG_BANK_SERDES_DIGITAL,
1266                                       MDIO_SERDES_DIGITAL_MISC1, reg_val);
1267
1268 }
1269
1270 static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params)
1271 {
1272         struct bnx2x *bp = params->bp;
1273         u16 val = 0;
1274
1275         /* configure the 48 bits for BAM AN */
1276
1277         /* set extended capabilities */
1278         if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
1279                 val |= MDIO_OVER_1G_UP1_2_5G;
1280         if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
1281                 val |= MDIO_OVER_1G_UP1_10G;
1282         CL45_WR_OVER_CL22(bp, params->port,
1283                               params->phy_addr,
1284                               MDIO_REG_BANK_OVER_1G,
1285                               MDIO_OVER_1G_UP1, val);
1286
1287         CL45_WR_OVER_CL22(bp, params->port,
1288                               params->phy_addr,
1289                               MDIO_REG_BANK_OVER_1G,
1290                               MDIO_OVER_1G_UP3, 0);
1291 }
1292
1293 static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u32 *ieee_fc)
1294 {
1295         *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
1296         /* resolve pause mode and advertisement
1297          * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
1298
1299         switch (params->req_flow_ctrl) {
1300         case BNX2X_FLOW_CTRL_AUTO:
1301                 if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH) {
1302                         *ieee_fc |=
1303                              MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1304                 } else {
1305                         *ieee_fc |=
1306                        MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1307                 }
1308                 break;
1309         case BNX2X_FLOW_CTRL_TX:
1310                 *ieee_fc |=
1311                        MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1312                 break;
1313
1314         case BNX2X_FLOW_CTRL_RX:
1315         case BNX2X_FLOW_CTRL_BOTH:
1316                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1317                 break;
1318
1319         case BNX2X_FLOW_CTRL_NONE:
1320         default:
1321                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
1322                 break;
1323         }
1324 }
1325
1326 static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params,
1327                                            u32 ieee_fc)
1328 {
1329         struct bnx2x *bp = params->bp;
1330         /* for AN, we are always publishing full duplex */
1331
1332         CL45_WR_OVER_CL22(bp, params->port,
1333                               params->phy_addr,
1334                               MDIO_REG_BANK_COMBO_IEEE0,
1335                               MDIO_COMBO_IEEE0_AUTO_NEG_ADV, (u16)ieee_fc);
1336 }
1337
1338 static void bnx2x_restart_autoneg(struct link_params *params)
1339 {
1340         struct bnx2x *bp = params->bp;
1341         u16 mii_control;
1342         DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
1343         /* Enable and restart BAM/CL37 aneg */
1344
1345         CL45_RD_OVER_CL22(bp, params->port,
1346                               params->phy_addr,
1347                               MDIO_REG_BANK_COMBO_IEEE0,
1348                               MDIO_COMBO_IEEE0_MII_CONTROL,
1349                               &mii_control);
1350         DP(NETIF_MSG_LINK,
1351                  "bnx2x_restart_autoneg mii_control before = 0x%x\n",
1352                  mii_control);
1353         CL45_WR_OVER_CL22(bp, params->port,
1354                               params->phy_addr,
1355                               MDIO_REG_BANK_COMBO_IEEE0,
1356                               MDIO_COMBO_IEEE0_MII_CONTROL,
1357                               (mii_control |
1358                                MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1359                                MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
1360 }
1361
1362 static void bnx2x_initialize_sgmii_process(struct link_params *params,
1363                                          struct link_vars *vars)
1364 {
1365         struct bnx2x *bp = params->bp;
1366         u16 control1;
1367
1368         /* in SGMII mode, the unicore is always slave */
1369
1370         CL45_RD_OVER_CL22(bp, params->port,
1371                               params->phy_addr,
1372                               MDIO_REG_BANK_SERDES_DIGITAL,
1373                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1374                       &control1);
1375         control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
1376         /* set sgmii mode (and not fiber) */
1377         control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
1378                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
1379                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
1380         CL45_WR_OVER_CL22(bp, params->port,
1381                               params->phy_addr,
1382                               MDIO_REG_BANK_SERDES_DIGITAL,
1383                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1384                               control1);
1385
1386         /* if forced speed */
1387         if (!(vars->line_speed == SPEED_AUTO_NEG)) {
1388                 /* set speed, disable autoneg */
1389                 u16 mii_control;
1390
1391                 CL45_RD_OVER_CL22(bp, params->port,
1392                                       params->phy_addr,
1393                                       MDIO_REG_BANK_COMBO_IEEE0,
1394                                       MDIO_COMBO_IEEE0_MII_CONTROL,
1395                                       &mii_control);
1396                 mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1397                                  MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
1398                                  MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
1399
1400                 switch (vars->line_speed) {
1401                 case SPEED_100:
1402                         mii_control |=
1403                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
1404                         break;
1405                 case SPEED_1000:
1406                         mii_control |=
1407                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
1408                         break;
1409                 case SPEED_10:
1410                         /* there is nothing to set for 10M */
1411                         break;
1412                 default:
1413                         /* invalid speed for SGMII */
1414                         DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
1415                                   vars->line_speed);
1416                         break;
1417                 }
1418
1419                 /* setting the full duplex */
1420                 if (params->req_duplex == DUPLEX_FULL)
1421                         mii_control |=
1422                                 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1423                 CL45_WR_OVER_CL22(bp, params->port,
1424                                       params->phy_addr,
1425                                       MDIO_REG_BANK_COMBO_IEEE0,
1426                                       MDIO_COMBO_IEEE0_MII_CONTROL,
1427                                       mii_control);
1428
1429         } else { /* AN mode */
1430                 /* enable and restart AN */
1431                 bnx2x_restart_autoneg(params);
1432         }
1433 }
1434
1435
1436 /*
1437  * link management
1438  */
1439
1440 static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
1441 {                                               /*  LD      LP   */
1442         switch (pause_result) {                 /* ASYM P ASYM P */
1443         case 0xb:                               /*   1  0   1  1 */
1444                 vars->flow_ctrl = BNX2X_FLOW_CTRL_TX;
1445                 break;
1446
1447         case 0xe:                               /*   1  1   1  0 */
1448                 vars->flow_ctrl = BNX2X_FLOW_CTRL_RX;
1449                 break;
1450
1451         case 0x5:                               /*   0  1   0  1 */
1452         case 0x7:                               /*   0  1   1  1 */
1453         case 0xd:                               /*   1  1   0  1 */
1454         case 0xf:                               /*   1  1   1  1 */
1455                 vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
1456                 break;
1457
1458         default:
1459                 break;
1460         }
1461 }
1462
1463 static u8 bnx2x_ext_phy_resove_fc(struct link_params *params,
1464                                   struct link_vars *vars)
1465 {
1466         struct bnx2x *bp = params->bp;
1467         u8 ext_phy_addr;
1468         u16 ld_pause;   /* local */
1469         u16 lp_pause;   /* link partner */
1470         u16 an_complete; /* AN complete */
1471         u16 pause_result;
1472         u8 ret = 0;
1473         u32 ext_phy_type;
1474         u8 port = params->port;
1475         ext_phy_addr = ((params->ext_phy_config &
1476                          PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1477                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1478
1479         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1480         /* read twice */
1481
1482         bnx2x_cl45_read(bp, port,
1483                       ext_phy_type,
1484                       ext_phy_addr,
1485                       MDIO_AN_DEVAD,
1486                       MDIO_AN_REG_STATUS, &an_complete);
1487         bnx2x_cl45_read(bp, port,
1488                       ext_phy_type,
1489                       ext_phy_addr,
1490                       MDIO_AN_DEVAD,
1491                       MDIO_AN_REG_STATUS, &an_complete);
1492
1493         if (an_complete & MDIO_AN_REG_STATUS_AN_COMPLETE) {
1494                 ret = 1;
1495                 bnx2x_cl45_read(bp, port,
1496                               ext_phy_type,
1497                               ext_phy_addr,
1498                               MDIO_AN_DEVAD,
1499                               MDIO_AN_REG_ADV_PAUSE, &ld_pause);
1500                 bnx2x_cl45_read(bp, port,
1501                               ext_phy_type,
1502                               ext_phy_addr,
1503                               MDIO_AN_DEVAD,
1504                               MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
1505                 pause_result = (ld_pause &
1506                                 MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
1507                 pause_result |= (lp_pause &
1508                                  MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
1509                 DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x \n",
1510                    pause_result);
1511                 bnx2x_pause_resolve(vars, pause_result);
1512                 if (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE &&
1513                      ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
1514                         bnx2x_cl45_read(bp, port,
1515                                       ext_phy_type,
1516                                       ext_phy_addr,
1517                                       MDIO_AN_DEVAD,
1518                                       MDIO_AN_REG_CL37_FC_LD, &ld_pause);
1519
1520                         bnx2x_cl45_read(bp, port,
1521                                       ext_phy_type,
1522                                       ext_phy_addr,
1523                                       MDIO_AN_DEVAD,
1524                                       MDIO_AN_REG_CL37_FC_LP, &lp_pause);
1525                         pause_result = (ld_pause &
1526                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
1527                         pause_result |= (lp_pause &
1528                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
1529
1530                         bnx2x_pause_resolve(vars, pause_result);
1531                         DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x \n",
1532                                  pause_result);
1533                 }
1534         }
1535         return ret;
1536 }
1537
1538
1539 static void bnx2x_flow_ctrl_resolve(struct link_params *params,
1540                                   struct link_vars *vars,
1541                                   u32 gp_status)
1542 {
1543         struct bnx2x *bp = params->bp;
1544         u16 ld_pause;   /* local driver */
1545         u16 lp_pause;   /* link partner */
1546         u16 pause_result;
1547
1548         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1549
1550         /* resolve from gp_status in case of AN complete and not sgmii */
1551         if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
1552             (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
1553             (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
1554             (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1555              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) {
1556                 CL45_RD_OVER_CL22(bp, params->port,
1557                                       params->phy_addr,
1558                                       MDIO_REG_BANK_COMBO_IEEE0,
1559                                       MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
1560                                       &ld_pause);
1561                 CL45_RD_OVER_CL22(bp, params->port,
1562                                       params->phy_addr,
1563                         MDIO_REG_BANK_COMBO_IEEE0,
1564                         MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
1565                         &lp_pause);
1566                 pause_result = (ld_pause &
1567                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
1568                 pause_result |= (lp_pause &
1569                                  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
1570                 DP(NETIF_MSG_LINK, "pause_result 0x%x\n", pause_result);
1571                 bnx2x_pause_resolve(vars, pause_result);
1572         } else if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
1573                    (bnx2x_ext_phy_resove_fc(params, vars))) {
1574                 return;
1575         } else {
1576                 if (params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO)
1577                         vars->flow_ctrl = params->req_fc_auto_adv;
1578                 else
1579                         vars->flow_ctrl = params->req_flow_ctrl;
1580         }
1581         DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
1582 }
1583
1584
1585 static u8 bnx2x_link_settings_status(struct link_params *params,
1586                                       struct link_vars *vars,
1587                                       u32 gp_status)
1588 {
1589         struct bnx2x *bp = params->bp;
1590         u16 new_line_speed;
1591         u8 rc = 0;
1592         vars->link_status = 0;
1593
1594         if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
1595                 DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n",
1596                          gp_status);
1597
1598                 vars->phy_link_up = 1;
1599                 vars->link_status |= LINK_STATUS_LINK_UP;
1600
1601                 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
1602                         vars->duplex = DUPLEX_FULL;
1603                 else
1604                         vars->duplex = DUPLEX_HALF;
1605
1606                 bnx2x_flow_ctrl_resolve(params, vars, gp_status);
1607
1608                 switch (gp_status & GP_STATUS_SPEED_MASK) {
1609                 case GP_STATUS_10M:
1610                         new_line_speed = SPEED_10;
1611                         if (vars->duplex == DUPLEX_FULL)
1612                                 vars->link_status |= LINK_10TFD;
1613                         else
1614                                 vars->link_status |= LINK_10THD;
1615                         break;
1616
1617                 case GP_STATUS_100M:
1618                         new_line_speed = SPEED_100;
1619                         if (vars->duplex == DUPLEX_FULL)
1620                                 vars->link_status |= LINK_100TXFD;
1621                         else
1622                                 vars->link_status |= LINK_100TXHD;
1623                         break;
1624
1625                 case GP_STATUS_1G:
1626                 case GP_STATUS_1G_KX:
1627                         new_line_speed = SPEED_1000;
1628                         if (vars->duplex == DUPLEX_FULL)
1629                                 vars->link_status |= LINK_1000TFD;
1630                         else
1631                                 vars->link_status |= LINK_1000THD;
1632                         break;
1633
1634                 case GP_STATUS_2_5G:
1635                         new_line_speed = SPEED_2500;
1636                         if (vars->duplex == DUPLEX_FULL)
1637                                 vars->link_status |= LINK_2500TFD;
1638                         else
1639                                 vars->link_status |= LINK_2500THD;
1640                         break;
1641
1642                 case GP_STATUS_5G:
1643                 case GP_STATUS_6G:
1644                         DP(NETIF_MSG_LINK,
1645                                  "link speed unsupported  gp_status 0x%x\n",
1646                                   gp_status);
1647                         return -EINVAL;
1648                         break;
1649                 case GP_STATUS_10G_KX4:
1650                 case GP_STATUS_10G_HIG:
1651                 case GP_STATUS_10G_CX4:
1652                         new_line_speed = SPEED_10000;
1653                         vars->link_status |= LINK_10GTFD;
1654                         break;
1655
1656                 case GP_STATUS_12G_HIG:
1657                         new_line_speed = SPEED_12000;
1658                         vars->link_status |= LINK_12GTFD;
1659                         break;
1660
1661                 case GP_STATUS_12_5G:
1662                         new_line_speed = SPEED_12500;
1663                         vars->link_status |= LINK_12_5GTFD;
1664                         break;
1665
1666                 case GP_STATUS_13G:
1667                         new_line_speed = SPEED_13000;
1668                         vars->link_status |= LINK_13GTFD;
1669                         break;
1670
1671                 case GP_STATUS_15G:
1672                         new_line_speed = SPEED_15000;
1673                         vars->link_status |= LINK_15GTFD;
1674                         break;
1675
1676                 case GP_STATUS_16G:
1677                         new_line_speed = SPEED_16000;
1678                         vars->link_status |= LINK_16GTFD;
1679                         break;
1680
1681                 default:
1682                         DP(NETIF_MSG_LINK,
1683                                   "link speed unsupported gp_status 0x%x\n",
1684                                   gp_status);
1685                 return -EINVAL;
1686                         break;
1687                 }
1688
1689                 /* Upon link speed change set the NIG into drain mode.
1690                 Comes to deals with possible FIFO glitch due to clk change
1691                 when speed is decreased without link down indicator */
1692                 if (new_line_speed != vars->line_speed) {
1693                         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
1694                                     + params->port*4, 0);
1695                         msleep(1);
1696                 }
1697                 vars->line_speed = new_line_speed;
1698                 vars->link_status |= LINK_STATUS_SERDES_LINK;
1699
1700                 if ((params->req_line_speed == SPEED_AUTO_NEG) &&
1701                     ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1702                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
1703                     (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1704                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
1705                     (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1706                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) ||
1707                      (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1708                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481))) {
1709                         vars->autoneg = AUTO_NEG_ENABLED;
1710
1711                         if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
1712                                 vars->autoneg |= AUTO_NEG_COMPLETE;
1713                                 vars->link_status |=
1714                                         LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
1715                         }
1716
1717                         vars->autoneg |= AUTO_NEG_PARALLEL_DETECTION_USED;
1718                         vars->link_status |=
1719                                 LINK_STATUS_PARALLEL_DETECTION_USED;
1720
1721                 }
1722                 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
1723                         vars->link_status |=
1724                                 LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
1725
1726                 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
1727                         vars->link_status |=
1728                                 LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
1729
1730         } else { /* link_down */
1731                 DP(NETIF_MSG_LINK, "phy link down\n");
1732
1733                 vars->phy_link_up = 0;
1734
1735                 vars->duplex = DUPLEX_FULL;
1736                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1737                 vars->autoneg = AUTO_NEG_DISABLED;
1738                 vars->mac_type = MAC_TYPE_NONE;
1739         }
1740
1741         DP(NETIF_MSG_LINK, "gp_status 0x%x  phy_link_up %x line_speed %x \n",
1742                  gp_status, vars->phy_link_up, vars->line_speed);
1743         DP(NETIF_MSG_LINK, "duplex %x  flow_ctrl 0x%x"
1744                  " autoneg 0x%x\n",
1745                  vars->duplex,
1746                  vars->flow_ctrl, vars->autoneg);
1747         DP(NETIF_MSG_LINK, "link_status 0x%x\n", vars->link_status);
1748
1749         return rc;
1750 }
1751
1752 static void bnx2x_set_gmii_tx_driver(struct link_params *params)
1753 {
1754         struct bnx2x *bp = params->bp;
1755         u16 lp_up2;
1756         u16 tx_driver;
1757         u16 bank;
1758
1759         /* read precomp */
1760         CL45_RD_OVER_CL22(bp, params->port,
1761                               params->phy_addr,
1762                               MDIO_REG_BANK_OVER_1G,
1763                               MDIO_OVER_1G_LP_UP2, &lp_up2);
1764
1765         /* bits [10:7] at lp_up2, positioned at [15:12] */
1766         lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
1767                    MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
1768                   MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
1769
1770         if (lp_up2 == 0)
1771                 return;
1772
1773         for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3;
1774               bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) {
1775                 CL45_RD_OVER_CL22(bp, params->port,
1776                                       params->phy_addr,
1777                                       bank,
1778                                       MDIO_TX0_TX_DRIVER, &tx_driver);
1779
1780                 /* replace tx_driver bits [15:12] */
1781                 if (lp_up2 !=
1782                     (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) {
1783                         tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
1784                         tx_driver |= lp_up2;
1785                         CL45_WR_OVER_CL22(bp, params->port,
1786                                               params->phy_addr,
1787                                               bank,
1788                                               MDIO_TX0_TX_DRIVER, tx_driver);
1789                 }
1790         }
1791 }
1792
1793 static u8 bnx2x_emac_program(struct link_params *params,
1794                            u32 line_speed, u32 duplex)
1795 {
1796         struct bnx2x *bp = params->bp;
1797         u8 port = params->port;
1798         u16 mode = 0;
1799
1800         DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
1801         bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
1802                      EMAC_REG_EMAC_MODE,
1803                      (EMAC_MODE_25G_MODE |
1804                      EMAC_MODE_PORT_MII_10M |
1805                      EMAC_MODE_HALF_DUPLEX));
1806         switch (line_speed) {
1807         case SPEED_10:
1808                 mode |= EMAC_MODE_PORT_MII_10M;
1809                 break;
1810
1811         case SPEED_100:
1812                 mode |= EMAC_MODE_PORT_MII;
1813                 break;
1814
1815         case SPEED_1000:
1816                 mode |= EMAC_MODE_PORT_GMII;
1817                 break;
1818
1819         case SPEED_2500:
1820                 mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
1821                 break;
1822
1823         default:
1824                 /* 10G not valid for EMAC */
1825                 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", line_speed);
1826                 return -EINVAL;
1827         }
1828
1829         if (duplex == DUPLEX_HALF)
1830                 mode |= EMAC_MODE_HALF_DUPLEX;
1831         bnx2x_bits_en(bp,
1832                     GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
1833                     mode);
1834
1835         bnx2x_set_led(bp, params->port, LED_MODE_OPER,
1836                     line_speed, params->hw_led_mode, params->chip_id);
1837         return 0;
1838 }
1839
1840 /*****************************************************************************/
1841 /*                           External Phy section                            */
1842 /*****************************************************************************/
1843 static void bnx2x_hw_reset(struct bnx2x *bp, u8 port)
1844 {
1845         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1846                        MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
1847         msleep(1);
1848         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1849                       MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
1850 }
1851
1852 static void bnx2x_ext_phy_reset(struct link_params *params,
1853                               struct link_vars   *vars)
1854 {
1855         struct bnx2x *bp = params->bp;
1856         u32 ext_phy_type;
1857         u8 ext_phy_addr = ((params->ext_phy_config &
1858                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1859                            PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1860         DP(NETIF_MSG_LINK, "Port %x: bnx2x_ext_phy_reset\n", params->port);
1861         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1862         /* The PHY reset is controled by GPIO 1
1863          * Give it 1ms of reset pulse
1864          */
1865         if (vars->phy_flags & PHY_XGXS_FLAG) {
1866
1867                 switch (ext_phy_type) {
1868                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
1869                         DP(NETIF_MSG_LINK, "XGXS Direct\n");
1870                         break;
1871
1872                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
1873                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
1874                         DP(NETIF_MSG_LINK, "XGXS 8705/8706\n");
1875
1876                         /* Restore normal power mode*/
1877                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1878                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1879                                           params->port);
1880
1881                         /* HW reset */
1882                         bnx2x_hw_reset(bp, params->port);
1883
1884                         bnx2x_cl45_write(bp, params->port,
1885                                        ext_phy_type,
1886                                        ext_phy_addr,
1887                                        MDIO_PMA_DEVAD,
1888                                        MDIO_PMA_REG_CTRL, 0xa040);
1889                         break;
1890                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
1891
1892                         /* Restore normal power mode*/
1893                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1894                                           MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1895                                           params->port);
1896
1897                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1898                                           MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1899                                           params->port);
1900
1901                         bnx2x_cl45_write(bp, params->port,
1902                                        ext_phy_type,
1903                                        ext_phy_addr,
1904                                        MDIO_PMA_DEVAD,
1905                                        MDIO_PMA_REG_CTRL,
1906                                        1<<15);
1907
1908                         break;
1909                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
1910                         /* Unset Low Power Mode and SW reset */
1911                         /* Restore normal power mode*/
1912                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1913                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1914                                           params->port);
1915
1916                         DP(NETIF_MSG_LINK, "XGXS 8072\n");
1917                         bnx2x_cl45_write(bp, params->port,
1918                                        ext_phy_type,
1919                                        ext_phy_addr,
1920                                        MDIO_PMA_DEVAD,
1921                                        MDIO_PMA_REG_CTRL,
1922                                        1<<15);
1923                         break;
1924                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
1925                         {
1926
1927                         /* Restore normal power mode*/
1928                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1929                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1930                                           params->port);
1931
1932                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1933                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1934                                           params->port);
1935
1936                         DP(NETIF_MSG_LINK, "XGXS 8073\n");
1937                         }
1938                         break;
1939
1940                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
1941                         DP(NETIF_MSG_LINK, "XGXS SFX7101\n");
1942
1943                         /* Restore normal power mode*/
1944                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1945                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1946                                           params->port);
1947
1948                         /* HW reset */
1949                         bnx2x_hw_reset(bp, params->port);
1950
1951                         break;
1952
1953                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
1954
1955                         /* Restore normal power mode*/
1956                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1957                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1958                                           params->port);
1959
1960                         /* HW reset */
1961                         bnx2x_hw_reset(bp, params->port);
1962
1963                         bnx2x_cl45_write(bp, params->port,
1964                                        ext_phy_type,
1965                                        ext_phy_addr,
1966                                        MDIO_PMA_DEVAD,
1967                                        MDIO_PMA_REG_CTRL,
1968                                        1<<15);
1969                         break;
1970                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
1971                         DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n");
1972                         break;
1973
1974                 default:
1975                         DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
1976                            params->ext_phy_config);
1977                         break;
1978                 }
1979
1980         } else { /* SerDes */
1981                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
1982                 switch (ext_phy_type) {
1983                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
1984                         DP(NETIF_MSG_LINK, "SerDes Direct\n");
1985                         break;
1986
1987                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
1988                         DP(NETIF_MSG_LINK, "SerDes 5482\n");
1989                         bnx2x_hw_reset(bp, params->port);
1990                         break;
1991
1992                 default:
1993                         DP(NETIF_MSG_LINK,
1994                                  "BAD SerDes ext_phy_config 0x%x\n",
1995                                  params->ext_phy_config);
1996                         break;
1997                 }
1998         }
1999 }
2000
2001
2002 static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port,
2003                                     u32 shmem_base, u32 spirom_ver)
2004 {
2005         DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x\n",
2006                  (u16)(spirom_ver>>16), (u16)spirom_ver);
2007         REG_WR(bp, shmem_base +
2008                    offsetof(struct shmem_region,
2009                             port_mb[port].ext_phy_fw_version),
2010                         spirom_ver);
2011 }
2012
2013 static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp, u8 port,
2014                                     u32 ext_phy_type, u8 ext_phy_addr,
2015                                     u32 shmem_base)
2016 {
2017         u16 fw_ver1, fw_ver2;
2018         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
2019                       MDIO_PMA_REG_ROM_VER1, &fw_ver1);
2020         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
2021                       MDIO_PMA_REG_ROM_VER2, &fw_ver2);
2022         bnx2x_save_spirom_version(bp, port, shmem_base,
2023                                 (u32)(fw_ver1<<16 | fw_ver2));
2024 }
2025
2026 static void bnx2x_bcm8072_external_rom_boot(struct link_params *params)
2027 {
2028         struct bnx2x *bp = params->bp;
2029         u8 port = params->port;
2030         u8 ext_phy_addr = ((params->ext_phy_config &
2031                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2032                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2033         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2034
2035         /* Need to wait 200ms after reset */
2036         msleep(200);
2037         /* Boot port from external ROM
2038          * Set ser_boot_ctl bit in the MISC_CTRL1 register
2039          */
2040         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2041                             MDIO_PMA_DEVAD,
2042                             MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2043
2044         /* Reset internal microprocessor */
2045         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2046                           MDIO_PMA_DEVAD,
2047                           MDIO_PMA_REG_GEN_CTRL,
2048                           MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2049         /* set micro reset = 0 */
2050         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2051                             MDIO_PMA_DEVAD,
2052                             MDIO_PMA_REG_GEN_CTRL,
2053                             MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2054         /* Reset internal microprocessor */
2055         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2056                           MDIO_PMA_DEVAD,
2057                           MDIO_PMA_REG_GEN_CTRL,
2058                           MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2059         /* wait for 100ms for code download via SPI port */
2060         msleep(100);
2061
2062         /* Clear ser_boot_ctl bit */
2063         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2064                             MDIO_PMA_DEVAD,
2065                             MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2066         /* Wait 100ms */
2067         msleep(100);
2068
2069         bnx2x_save_bcm_spirom_ver(bp, port,
2070                                 ext_phy_type,
2071                                 ext_phy_addr,
2072                                 params->shmem_base);
2073 }
2074
2075 static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
2076 {
2077         /* This is only required for 8073A1, version 102 only */
2078
2079         struct bnx2x *bp = params->bp;
2080         u8 ext_phy_addr = ((params->ext_phy_config &
2081                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2082                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2083         u16 val;
2084
2085         /* Read 8073 HW revision*/
2086         bnx2x_cl45_read(bp, params->port,
2087                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2088                       ext_phy_addr,
2089                       MDIO_PMA_DEVAD,
2090                       MDIO_PMA_REG_8073_CHIP_REV, &val);
2091
2092         if (val != 1) {
2093                 /* No need to workaround in 8073 A1 */
2094                 return 0;
2095         }
2096
2097         bnx2x_cl45_read(bp, params->port,
2098                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2099                       ext_phy_addr,
2100                       MDIO_PMA_DEVAD,
2101                       MDIO_PMA_REG_ROM_VER2, &val);
2102
2103         /* SNR should be applied only for version 0x102 */
2104         if (val != 0x102)
2105                 return 0;
2106
2107         return 1;
2108 }
2109
2110 static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
2111 {
2112         struct bnx2x *bp = params->bp;
2113         u8 ext_phy_addr = ((params->ext_phy_config &
2114                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2115                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2116         u16 val, cnt, cnt1 ;
2117
2118         bnx2x_cl45_read(bp, params->port,
2119                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2120                       ext_phy_addr,
2121                       MDIO_PMA_DEVAD,
2122                       MDIO_PMA_REG_8073_CHIP_REV, &val);
2123
2124         if (val > 0) {
2125                 /* No need to workaround in 8073 A1 */
2126                 return 0;
2127         }
2128         /* XAUI workaround in 8073 A0: */
2129
2130         /* After loading the boot ROM and restarting Autoneg,
2131         poll Dev1, Reg $C820: */
2132
2133         for (cnt = 0; cnt < 1000; cnt++) {
2134                 bnx2x_cl45_read(bp, params->port,
2135                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2136                               ext_phy_addr,
2137                               MDIO_PMA_DEVAD,
2138                               MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
2139                               &val);
2140                   /* If bit [14] = 0 or bit [13] = 0, continue on with
2141                    system initialization (XAUI work-around not required,
2142                     as these bits indicate 2.5G or 1G link up). */
2143                 if (!(val & (1<<14)) || !(val & (1<<13))) {
2144                         DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
2145                         return 0;
2146                 } else if (!(val & (1<<15))) {
2147                         DP(NETIF_MSG_LINK, "clc bit 15 went off\n");
2148                          /* If bit 15 is 0, then poll Dev1, Reg $C841 until
2149                           it's MSB (bit 15) goes to 1 (indicating that the
2150                           XAUI workaround has completed),
2151                           then continue on with system initialization.*/
2152                         for (cnt1 = 0; cnt1 < 1000; cnt1++) {
2153                                 bnx2x_cl45_read(bp, params->port,
2154                                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2155                                         ext_phy_addr,
2156                                         MDIO_PMA_DEVAD,
2157                                         MDIO_PMA_REG_8073_XAUI_WA, &val);
2158                                 if (val & (1<<15)) {
2159                                         DP(NETIF_MSG_LINK,
2160                                           "XAUI workaround has completed\n");
2161                                         return 0;
2162                                  }
2163                                  msleep(3);
2164                         }
2165                         break;
2166                 }
2167                 msleep(3);
2168         }
2169         DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
2170         return -EINVAL;
2171
2172 }
2173
2174 static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port,
2175                                           u8 ext_phy_addr, u32 shmem_base)
2176 {
2177         /* Boot port from external ROM  */
2178         /* EDC grst */
2179         bnx2x_cl45_write(bp, port,
2180                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2181                        ext_phy_addr,
2182                        MDIO_PMA_DEVAD,
2183                        MDIO_PMA_REG_GEN_CTRL,
2184                        0x0001);
2185
2186         /* ucode reboot and rst */
2187         bnx2x_cl45_write(bp, port,
2188                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2189                        ext_phy_addr,
2190                        MDIO_PMA_DEVAD,
2191                        MDIO_PMA_REG_GEN_CTRL,
2192                        0x008c);
2193
2194         bnx2x_cl45_write(bp, port,
2195                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2196                        ext_phy_addr,
2197                        MDIO_PMA_DEVAD,
2198                        MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2199
2200         /* Reset internal microprocessor */
2201         bnx2x_cl45_write(bp, port,
2202                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2203                        ext_phy_addr,
2204                        MDIO_PMA_DEVAD,
2205                        MDIO_PMA_REG_GEN_CTRL,
2206                        MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2207
2208         /* Release srst bit */
2209         bnx2x_cl45_write(bp, port,
2210                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2211                        ext_phy_addr,
2212                        MDIO_PMA_DEVAD,
2213                        MDIO_PMA_REG_GEN_CTRL,
2214                        MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2215
2216         /* wait for 100ms for code download via SPI port */
2217         msleep(100);
2218
2219         /* Clear ser_boot_ctl bit */
2220         bnx2x_cl45_write(bp, port,
2221                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2222                        ext_phy_addr,
2223                        MDIO_PMA_DEVAD,
2224                        MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2225
2226         bnx2x_save_bcm_spirom_ver(bp, port,
2227                                 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2228                                 ext_phy_addr,
2229                                 shmem_base);
2230 }
2231
2232 static void bnx2x_bcm8726_external_rom_boot(struct link_params *params)
2233 {
2234         struct bnx2x *bp = params->bp;
2235         u8 port = params->port;
2236         u8 ext_phy_addr = ((params->ext_phy_config &
2237                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2238                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2239         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2240
2241         /* Need to wait 100ms after reset */
2242         msleep(100);
2243
2244         /* Set serial boot control for external load */
2245         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2246                        MDIO_PMA_DEVAD,
2247                        MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2248
2249         /* Micro controller re-boot */
2250         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2251                        MDIO_PMA_DEVAD,
2252                        MDIO_PMA_REG_GEN_CTRL,
2253                        MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2254
2255         /* Set soft reset */
2256         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2257                        MDIO_PMA_DEVAD,
2258                        MDIO_PMA_REG_GEN_CTRL,
2259                        MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2260
2261         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2262                        MDIO_PMA_DEVAD,
2263                        MDIO_PMA_REG_GEN_CTRL2,
2264                        0x73A0);
2265
2266         /* Clear soft reset.
2267         Will automatically reset micro-controller re-boot */
2268         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2269                        MDIO_PMA_DEVAD,
2270                        MDIO_PMA_REG_GEN_CTRL,
2271                        MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2272
2273         /* wait for 150ms for microcode load */
2274         msleep(150);
2275
2276         /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
2277         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2278                        MDIO_PMA_DEVAD,
2279                        MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2280
2281         msleep(200);
2282         bnx2x_save_bcm_spirom_ver(bp, port,
2283                                 ext_phy_type,
2284                                 ext_phy_addr,
2285                                 params->shmem_base);
2286 }
2287
2288 static void bnx2x_bcm8726_set_transmitter(struct bnx2x *bp, u8 port,
2289                                         u8 ext_phy_addr, u8 tx_en)
2290 {
2291         u16 val;
2292         DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n",
2293                  tx_en, port);
2294         /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
2295         bnx2x_cl45_read(bp, port,
2296                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2297                       ext_phy_addr,
2298                       MDIO_PMA_DEVAD,
2299                       MDIO_PMA_REG_PHY_IDENTIFIER,
2300                       &val);
2301
2302         if (tx_en)
2303                 val &= ~(1<<15);
2304         else
2305                 val |= (1<<15);
2306
2307         bnx2x_cl45_write(bp, port,
2308                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2309                        ext_phy_addr,
2310                        MDIO_PMA_DEVAD,
2311                        MDIO_PMA_REG_PHY_IDENTIFIER,
2312                        val);
2313 }
2314
2315
2316 static u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr,
2317                                      u8 byte_cnt, u8 *o_buf) {
2318         struct bnx2x *bp = params->bp;
2319         u16 val, i;
2320         u8 port = params->port;
2321         u8 ext_phy_addr = ((params->ext_phy_config &
2322                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2323                            PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2324         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2325         if (byte_cnt > 16) {
2326                 DP(NETIF_MSG_LINK, "Reading from eeprom is"
2327                             " is limited to 0xf\n");
2328                 return -EINVAL;
2329         }
2330         /* Set the read command byte count */
2331         bnx2x_cl45_write(bp, port,
2332                        ext_phy_type,
2333                        ext_phy_addr,
2334                        MDIO_PMA_DEVAD,
2335                        MDIO_PMA_REG_8726_TWO_WIRE_BYTE_CNT,
2336                        (byte_cnt | 0xa000));
2337
2338         /* Set the read command address */
2339         bnx2x_cl45_write(bp, port,
2340                        ext_phy_type,
2341                        ext_phy_addr,
2342                        MDIO_PMA_DEVAD,
2343                        MDIO_PMA_REG_8726_TWO_WIRE_MEM_ADDR,
2344                        addr);
2345
2346         /* Activate read command */
2347         bnx2x_cl45_write(bp, port,
2348                        ext_phy_type,
2349                        ext_phy_addr,
2350                        MDIO_PMA_DEVAD,
2351                        MDIO_PMA_REG_8726_TWO_WIRE_CTRL,
2352                        0x2c0f);
2353
2354         /* Wait up to 500us for command complete status */
2355         for (i = 0; i < 100; i++) {
2356                 bnx2x_cl45_read(bp, port,
2357                               ext_phy_type,
2358                               ext_phy_addr,
2359                               MDIO_PMA_DEVAD,
2360                               MDIO_PMA_REG_8726_TWO_WIRE_CTRL, &val);
2361                 if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) ==
2362                     MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE)
2363                         break;
2364                 udelay(5);
2365         }
2366
2367         if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) !=
2368                     MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE) {
2369                 DP(NETIF_MSG_LINK,
2370                          "Got bad status 0x%x when reading from SFP+ EEPROM\n",
2371                          (val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK));
2372                 return -EINVAL;
2373         }
2374
2375         /* Read the buffer */
2376         for (i = 0; i < byte_cnt; i++) {
2377                 bnx2x_cl45_read(bp, port,
2378                               ext_phy_type,
2379                               ext_phy_addr,
2380                               MDIO_PMA_DEVAD,
2381                               MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
2382                 o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
2383         }
2384
2385         for (i = 0; i < 100; i++) {
2386                 bnx2x_cl45_read(bp, port,
2387                               ext_phy_type,
2388                               ext_phy_addr,
2389                               MDIO_PMA_DEVAD,
2390                               MDIO_PMA_REG_8726_TWO_WIRE_CTRL, &val);
2391                 if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) ==
2392                     MDIO_PMA_REG_8726_TWO_WIRE_STATUS_IDLE)
2393                         return 0;;
2394                 msleep(1);
2395         }
2396         return -EINVAL;
2397 }
2398
2399
2400 static u8 bnx2x_get_sfp_module_type(struct link_params *params,
2401                                   u8 *module_type)
2402 {
2403         struct bnx2x *bp = params->bp;
2404         u8 val;
2405         *module_type = SFP_MODULE_TYPE_UNKNOWN;
2406
2407         /* First check for copper cable */
2408         if (bnx2x_read_sfp_module_eeprom(params,
2409                                        SFP_EEPROM_CON_TYPE_ADDR,
2410                                        1,
2411                                        &val) != 0) {
2412                 DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM");
2413                 return -EINVAL;
2414         }
2415
2416         switch (val) {
2417         case SFP_EEPROM_CON_TYPE_VAL_COPPER:
2418         {
2419                 u8 copper_module_type;
2420                 /* Check if its active cable( includes SFP+ module)
2421                 of passive cable*/
2422                 if (bnx2x_read_sfp_module_eeprom(params,
2423                                                SFP_EEPROM_FC_TX_TECH_ADDR,
2424                                                1,
2425                                                &copper_module_type) !=
2426                     0) {
2427                         DP(NETIF_MSG_LINK,
2428                                 "Failed to read copper-cable-type"
2429                                 " from SFP+ EEPROM\n");
2430                         return -EINVAL;
2431                 }
2432
2433                 if (copper_module_type &
2434                     SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
2435                         DP(NETIF_MSG_LINK, "Active Copper cable detected\n");
2436                         *module_type = SFP_MODULE_TYPE_ACTIVE_COPPER_CABLE;
2437                 } else if (copper_module_type &
2438                         SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
2439                                 DP(NETIF_MSG_LINK, "Passive Copper"
2440                                             " cable detected\n");
2441                                 *module_type =
2442                                       SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE;
2443                 } else {
2444                         DP(NETIF_MSG_LINK, "Unknown copper-cable-"
2445                                      "type 0x%x !!!\n", copper_module_type);
2446                         return -EINVAL;
2447                 }
2448                 break;
2449         }
2450         case SFP_EEPROM_CON_TYPE_VAL_LC:
2451                 DP(NETIF_MSG_LINK, "Optic module detected\n");
2452                 *module_type = SFP_MODULE_TYPE_LC;
2453                 break;
2454
2455         default:
2456                 DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n",
2457                          val);
2458                 return -EINVAL;
2459         }
2460         return 0;
2461 }
2462
2463
2464 /* This function read the relevant field from the module ( SFP+ ),
2465         and verify it is compliant with this board */
2466 static u8 bnx2x_verify_sfp_module(struct link_params *params,
2467                                 u8 module_type)
2468 {
2469         struct bnx2x *bp = params->bp;
2470         u8 *str_p, *tmp_buf;
2471         u16 i;
2472
2473 #define COMPLIANCE_STR_CNT 6
2474         u8 *compliance_str[] = {"Broadcom", "JDSU", "Molex Inc", "PICOLIGHT",
2475                 "FINISAR CORP.   ", "Amphenol"};
2476         u8 buf[SFP_EEPROM_VENDOR_NAME_SIZE];
2477         /* Passive Copper cables are allowed to participate,
2478         since the module is hardwired to the copper cable */
2479
2480         if (!(params->feature_config_flags &
2481              FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED)) {
2482                 DP(NETIF_MSG_LINK, "NOT enforcing module verification\n");
2483                 return 0;
2484         }
2485
2486         if (module_type != SFP_MODULE_TYPE_LC) {
2487                 DP(NETIF_MSG_LINK, "No need to verify copper cable\n");
2488                 return 0;
2489         }
2490
2491         /* In case of non copper cable or Active copper cable,
2492                 verify that the SFP+ module is compliant with this board*/
2493         if (bnx2x_read_sfp_module_eeprom(params,
2494                                        SFP_EEPROM_VENDOR_NAME_ADDR,
2495                                        SFP_EEPROM_VENDOR_NAME_SIZE,
2496                                        buf) != 0) {
2497                 DP(NETIF_MSG_LINK, "Failed to read Vendor-Name from"
2498                             " module EEPROM\n");
2499                 return -EINVAL;
2500         }
2501         for (i = 0; i < COMPLIANCE_STR_CNT; i++) {
2502                 str_p = compliance_str[i];
2503                 tmp_buf = buf;
2504                 while (*str_p) {
2505                         if ((u8)(*tmp_buf) != (u8)(*str_p))
2506                                 break;
2507                         str_p++;
2508                         tmp_buf++;
2509                 }
2510
2511                 if (!(*str_p)) {
2512                         DP(NETIF_MSG_LINK, "SFP+ Module verified, "
2513                                      "index=%x\n", i);
2514                         return 0;
2515                 }
2516         }
2517         DP(NETIF_MSG_LINK, "Incompliant SFP+ module. Disable module !!!\n");
2518         return -EINVAL;
2519 }
2520
2521
2522 static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params,
2523                                         u8 module_type)
2524 {
2525         struct bnx2x *bp = params->bp;
2526         u8 port = params->port;
2527         u8 options[SFP_EEPROM_OPTIONS_SIZE];
2528         u8 limiting_mode;
2529         u8 ext_phy_addr = ((params->ext_phy_config &
2530                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2531                            PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2532         u16 cur_limiting_mode;
2533         if (bnx2x_read_sfp_module_eeprom(params,
2534                                        SFP_EEPROM_OPTIONS_ADDR,
2535                                        SFP_EEPROM_OPTIONS_SIZE,
2536                                        options) != 0) {
2537                 DP(NETIF_MSG_LINK, "Failed to read Option field from"
2538                             " module EEPROM\n");
2539                 return -EINVAL;
2540         }
2541         limiting_mode = !(options[0] &
2542                           SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK);
2543
2544         bnx2x_cl45_read(bp, port,
2545                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2546                       ext_phy_addr,
2547                       MDIO_PMA_DEVAD,
2548                       MDIO_PMA_REG_ROM_VER2,
2549                       &cur_limiting_mode);
2550         DP(NETIF_MSG_LINK, "Current Limiting mode is 0x%x\n",
2551                  cur_limiting_mode);
2552
2553         if (limiting_mode &&
2554             (module_type != SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE)) {
2555                 DP(NETIF_MSG_LINK,
2556                          "Module options = 0x%x.Setting LIMITING MODE\n",
2557                          options[0]);
2558                 bnx2x_cl45_write(bp, port,
2559                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2560                                ext_phy_addr,
2561                                MDIO_PMA_DEVAD,
2562                                MDIO_PMA_REG_ROM_VER2,
2563                                SFP_LIMITING_MODE_VALUE);
2564         } else { /* LRM mode ( default )*/
2565
2566                 DP(NETIF_MSG_LINK, "Module options = 0x%x.Setting LRM MODE\n",
2567                          options[0]);
2568
2569                 /* Changing to LRM mode takes quite few seconds.
2570                 So do it only if current mode is limiting
2571                 ( default is LRM )*/
2572                 if (cur_limiting_mode != SFP_LIMITING_MODE_VALUE)
2573                         return 0;
2574
2575                 bnx2x_cl45_write(bp, port,
2576                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2577                                ext_phy_addr,
2578                                MDIO_PMA_DEVAD,
2579                                MDIO_PMA_REG_LRM_MODE,
2580                                0);
2581                 bnx2x_cl45_write(bp, port,
2582                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2583                                ext_phy_addr,
2584                                MDIO_PMA_DEVAD,
2585                                MDIO_PMA_REG_ROM_VER2,
2586                                0x128);
2587                 bnx2x_cl45_write(bp, port,
2588                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2589                                ext_phy_addr,
2590                                MDIO_PMA_DEVAD,
2591                                MDIO_PMA_REG_MISC_CTRL0,
2592                                0x4008);
2593                 bnx2x_cl45_write(bp, port,
2594                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2595                                ext_phy_addr,
2596                                MDIO_PMA_DEVAD,
2597                                MDIO_PMA_REG_LRM_MODE,
2598                                0xaaaa);
2599         }
2600         return 0;
2601 }
2602
2603 static u8 bnx2x_wait_for_sfp_module_initialized(struct link_params *params)
2604 {
2605         u8 val;
2606         struct bnx2x *bp = params->bp;
2607         u16 timeout;
2608         /* Initialization time after hot-plug may take up to 300ms for some
2609         phys type ( e.g. JDSU ) */
2610         for (timeout = 0; timeout < 60; timeout++) {
2611                 if (bnx2x_read_sfp_module_eeprom(params, 1, 1, &val)
2612                     == 0) {
2613                         DP(NETIF_MSG_LINK, "SFP+ module initialization "
2614                                      "took %d ms\n", timeout * 5);
2615                         return 0;
2616                 }
2617                 msleep(5);
2618         }
2619         return -EINVAL;
2620 }
2621
2622 static u8 bnx2x_sfp_module_detection(struct link_params *params)
2623 {
2624         struct bnx2x *bp = params->bp;
2625         u8 module_type;
2626         u8 ext_phy_addr = ((params->ext_phy_config &
2627                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2628                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2629         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2630
2631         if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
2632                 DP(NETIF_MSG_LINK, "Module detection is not required "
2633                             "for this phy\n");
2634                 return 0;
2635         }
2636
2637         DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
2638                  params->port);
2639
2640         if (bnx2x_get_sfp_module_type(params,
2641                                     &module_type) != 0) {
2642                 DP(NETIF_MSG_LINK, "Failed to get valid module type\n");
2643                 if (!(params->feature_config_flags &
2644                       FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED)) {
2645                         /* In case module detection is disabled, it trys to
2646                         link up. The issue that can happen here is LRM /
2647                         LIMITING mode which set according to the module-type*/
2648                         DP(NETIF_MSG_LINK, "Unable to read module-type."
2649                                     "Probably due to Bit Stretching."
2650                                     " Proceeding...\n");
2651                 } else {
2652                         return -EINVAL;
2653                 }
2654         } else if (bnx2x_verify_sfp_module(params, module_type) !=
2655                    0) {
2656                 /* check SFP+ module compatibility */
2657                 DP(NETIF_MSG_LINK, "Module verification failed!!\n");
2658                 /* Turn on fault module-detected led */
2659                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
2660                                   MISC_REGISTERS_GPIO_HIGH,
2661                                   params->port);
2662                 return -EINVAL;
2663         }
2664
2665         /* Turn off fault module-detected led */
2666         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
2667                           MISC_REGISTERS_GPIO_LOW,
2668                           params->port);
2669
2670         /* Check and set limiting mode / LRM mode */
2671         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 = params->bp;
4216         u32 ext_phy_type = 0;
4217         u32 spirom_ver = 0;
4218         u8 status = 0 ;
4219
4220         if (version == NULL || params == NULL)
4221                 return -EINVAL;
4222
4223         spirom_ver = REG_RD(bp, params->shmem_base +
4224                    offsetof(struct shmem_region,
4225                             port_mb[params->port].ext_phy_fw_version));
4226
4227         /* reset the returned value to zero */
4228         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4229         switch (ext_phy_type) {
4230         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4231
4232                 if (len < 5)
4233                         return -EINVAL;
4234
4235                 version[0] = (spirom_ver & 0xFF);
4236                 version[1] = (spirom_ver & 0xFF00) >> 8;
4237                 version[2] = (spirom_ver & 0xFF0000) >> 16;
4238                 version[3] = (spirom_ver & 0xFF000000) >> 24;
4239                 version[4] = '\0';
4240
4241                 break;
4242         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4243         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4244         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
4245         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
4246         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
4247         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
4248                 status = bnx2x_format_ver(spirom_ver, version, len);
4249                 break;
4250         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4251                 break;
4252
4253         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
4254                 DP(NETIF_MSG_LINK, "bnx2x_get_ext_phy_fw_version:"
4255                                     " type is FAILURE!\n");
4256                 status = -EINVAL;
4257                 break;
4258
4259         default:
4260                 break;
4261         }
4262         return status;
4263 }
4264
4265 static void bnx2x_set_xgxs_loopback(struct link_params *params,
4266                                   struct link_vars *vars,
4267                                   u8 is_10g)
4268 {
4269         u8 port = params->port;
4270         struct bnx2x *bp = params->bp;
4271
4272         if (is_10g) {
4273                 u32 md_devad;
4274
4275                 DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
4276
4277                 /* change the uni_phy_addr in the nig */
4278                 md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
4279                                           port*0x18));
4280
4281                 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
4282
4283                 bnx2x_cl45_write(bp, port, 0,
4284                                params->phy_addr,
4285                                5,
4286                                (MDIO_REG_BANK_AER_BLOCK +
4287                                 (MDIO_AER_BLOCK_AER_REG & 0xf)),
4288                                0x2800);
4289
4290                 bnx2x_cl45_write(bp, port, 0,
4291                                params->phy_addr,
4292                                5,
4293                                (MDIO_REG_BANK_CL73_IEEEB0 +
4294                                 (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
4295                                0x6041);
4296                 msleep(200);
4297                 /* set aer mmd back */
4298                 bnx2x_set_aer_mmd(params, vars);
4299
4300                 /* and md_devad */
4301                 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
4302                             md_devad);
4303
4304         } else {
4305                 u16 mii_control;
4306
4307                 DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
4308
4309                 CL45_RD_OVER_CL22(bp, port,
4310                                       params->phy_addr,
4311                                       MDIO_REG_BANK_COMBO_IEEE0,
4312                                       MDIO_COMBO_IEEE0_MII_CONTROL,
4313                                       &mii_control);
4314
4315                 CL45_WR_OVER_CL22(bp, port,
4316                                       params->phy_addr,
4317                                       MDIO_REG_BANK_COMBO_IEEE0,
4318                                       MDIO_COMBO_IEEE0_MII_CONTROL,
4319                                       (mii_control |
4320                                        MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK));
4321         }
4322 }
4323
4324
4325 static void bnx2x_ext_phy_loopback(struct link_params *params)
4326 {
4327         struct bnx2x *bp = params->bp;
4328         u8 ext_phy_addr;
4329         u32 ext_phy_type;
4330
4331         if (params->switch_cfg == SWITCH_CFG_10G) {
4332                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4333                 /* CL37 Autoneg Enabled */
4334                 ext_phy_addr = ((params->ext_phy_config &
4335                                         PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4336                                         PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4337                 switch (ext_phy_type) {
4338                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4339                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
4340                         DP(NETIF_MSG_LINK,
4341                                 "ext_phy_loopback: We should not get here\n");
4342                         break;
4343                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
4344                         DP(NETIF_MSG_LINK, "ext_phy_loopback: 8705\n");
4345                         break;
4346                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
4347                         DP(NETIF_MSG_LINK, "ext_phy_loopback: 8706\n");
4348                         break;
4349                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
4350                         DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
4351                         bnx2x_cl45_write(bp, params->port, ext_phy_type,
4352                                        ext_phy_addr,
4353                                        MDIO_PMA_DEVAD,
4354                                        MDIO_PMA_REG_CTRL,
4355                                        0x0001);
4356                         break;
4357                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4358                         /* SFX7101_XGXS_TEST1 */
4359                         bnx2x_cl45_write(bp, params->port, ext_phy_type,
4360                                        ext_phy_addr,
4361                                        MDIO_XS_DEVAD,
4362                                        MDIO_XS_SFX7101_XGXS_TEST1,
4363                                        0x100);
4364                         DP(NETIF_MSG_LINK,
4365                                 "ext_phy_loopback: set ext phy loopback\n");
4366                         break;
4367                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4368
4369                         break;
4370                 } /* switch external PHY type */
4371         } else {
4372                 /* serdes */
4373                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
4374                 ext_phy_addr = (params->ext_phy_config  &
4375                 PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK)
4376                 >> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT;
4377         }
4378 }
4379
4380
4381 /*
4382  *------------------------------------------------------------------------
4383  * bnx2x_override_led_value -
4384  *
4385  * Override the led value of the requsted led
4386  *
4387  *------------------------------------------------------------------------
4388  */
4389 u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port,
4390                           u32 led_idx, u32 value)
4391 {
4392         u32 reg_val;
4393
4394         /* If port 0 then use EMAC0, else use EMAC1*/
4395         u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
4396
4397         DP(NETIF_MSG_LINK,
4398                  "bnx2x_override_led_value() port %x led_idx %d value %d\n",
4399                  port, led_idx, value);
4400
4401         switch (led_idx) {
4402         case 0: /* 10MB led */
4403                 /* Read the current value of the LED register in
4404                 the EMAC block */
4405                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4406                 /* Set the OVERRIDE bit to 1 */
4407                 reg_val |= EMAC_LED_OVERRIDE;
4408                 /* If value is 1, set the 10M_OVERRIDE bit,
4409                 otherwise reset it.*/
4410                 reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) :
4411                         (reg_val & ~EMAC_LED_10MB_OVERRIDE);
4412                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4413                 break;
4414         case 1: /*100MB led    */
4415                 /*Read the current value of the LED register in
4416                 the EMAC block */
4417                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4418                 /*  Set the OVERRIDE bit to 1 */
4419                 reg_val |= EMAC_LED_OVERRIDE;
4420                 /*  If value is 1, set the 100M_OVERRIDE bit,
4421                 otherwise reset it.*/
4422                 reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) :
4423                         (reg_val & ~EMAC_LED_100MB_OVERRIDE);
4424                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4425                 break;
4426         case 2: /* 1000MB led */
4427                 /* Read the current value of the LED register in the
4428                 EMAC block */
4429                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4430                 /* Set the OVERRIDE bit to 1 */
4431                 reg_val |= EMAC_LED_OVERRIDE;
4432                 /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
4433                 reset it. */
4434                 reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) :
4435                         (reg_val & ~EMAC_LED_1000MB_OVERRIDE);
4436                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4437                 break;
4438         case 3: /* 2500MB led */
4439                 /*  Read the current value of the LED register in the
4440                 EMAC block*/
4441                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4442                 /* Set the OVERRIDE bit to 1 */
4443                 reg_val |= EMAC_LED_OVERRIDE;
4444                 /*  If value is 1, set the 2500M_OVERRIDE bit, otherwise
4445                 reset it.*/
4446                 reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) :
4447                         (reg_val & ~EMAC_LED_2500MB_OVERRIDE);
4448                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4449                 break;
4450         case 4: /*10G led */
4451                 if (port == 0) {
4452                         REG_WR(bp, NIG_REG_LED_10G_P0,
4453                                     value);
4454                 } else {
4455                         REG_WR(bp, NIG_REG_LED_10G_P1,
4456                                     value);
4457                 }
4458                 break;
4459         case 5: /* TRAFFIC led */
4460                 /* Find if the traffic control is via BMAC or EMAC */
4461                 if (port == 0)
4462                         reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN);
4463                 else
4464                         reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN);
4465
4466                 /*  Override the traffic led in the EMAC:*/
4467                 if (reg_val == 1) {
4468                         /* Read the current value of the LED register in
4469                         the EMAC block */
4470                         reg_val = REG_RD(bp, emac_base +
4471                                              EMAC_REG_EMAC_LED);
4472                         /* Set the TRAFFIC_OVERRIDE bit to 1 */
4473                         reg_val |= EMAC_LED_OVERRIDE;
4474                         /* If value is 1, set the TRAFFIC bit, otherwise
4475                         reset it.*/
4476                         reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) :
4477                                 (reg_val & ~EMAC_LED_TRAFFIC);
4478                         REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4479                 } else { /* Override the traffic led in the BMAC: */
4480                         REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
4481                                    + port*4, 1);
4482                         REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4,
4483                                     value);
4484                 }
4485                 break;
4486         default:
4487                 DP(NETIF_MSG_LINK,
4488                          "bnx2x_override_led_value() unknown led index %d "
4489                          "(should be 0-5)\n", led_idx);
4490                 return -EINVAL;
4491         }
4492
4493         return 0;
4494 }
4495
4496
4497 u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed,
4498                u16 hw_led_mode, u32 chip_id)
4499 {
4500         u8 rc = 0;
4501         u32 tmp;
4502         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
4503         DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
4504         DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
4505                  speed, hw_led_mode);
4506         switch (mode) {
4507         case LED_MODE_OFF:
4508                 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
4509                 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
4510                            SHARED_HW_CFG_LED_MAC1);
4511
4512                 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
4513                 EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
4514                 break;
4515
4516         case LED_MODE_OPER:
4517                 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode);
4518                 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 +
4519                            port*4, 0);
4520                 /* Set blinking rate to ~15.9Hz */
4521                 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
4522                            LED_BLINK_RATE_VAL);
4523                 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
4524                            port*4, 1);
4525                 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
4526                 EMAC_WR(bp, EMAC_REG_EMAC_LED,
4527                             (tmp & (~EMAC_LED_OVERRIDE)));
4528
4529                 if (!CHIP_IS_E1H(bp) &&
4530                     ((speed == SPEED_2500) ||
4531                      (speed == SPEED_1000) ||
4532                      (speed == SPEED_100) ||
4533                      (speed == SPEED_10))) {
4534                         /* On Everest 1 Ax chip versions for speeds less than
4535                         10G LED scheme is different */
4536                         REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
4537                                    + port*4, 1);
4538                         REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
4539                                    port*4, 0);
4540                         REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
4541                                    port*4, 1);
4542                 }
4543                 break;
4544
4545         default:
4546                 rc = -EINVAL;
4547                 DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
4548                          mode);
4549                 break;
4550         }
4551         return rc;
4552
4553 }
4554
4555 u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars)
4556 {
4557         struct bnx2x *bp = params->bp;
4558         u16 gp_status = 0;
4559
4560         CL45_RD_OVER_CL22(bp, params->port,
4561                               params->phy_addr,
4562                               MDIO_REG_BANK_GP_STATUS,
4563                               MDIO_GP_STATUS_TOP_AN_STATUS1,
4564                               &gp_status);
4565         /* link is up only if both local phy and external phy are up */
4566         if ((gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) &&
4567             bnx2x_ext_phy_is_link_up(params, vars))
4568                 return 0;
4569
4570         return -ESRCH;
4571 }
4572
4573 static u8 bnx2x_link_initialize(struct link_params *params,
4574                               struct link_vars *vars)
4575 {
4576         struct bnx2x *bp = params->bp;
4577         u8 port = params->port;
4578         u8 rc = 0;
4579         u8 non_ext_phy;
4580         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4581         /* Activate the external PHY */
4582         bnx2x_ext_phy_reset(params, vars);
4583
4584         bnx2x_set_aer_mmd(params, vars);
4585
4586         if (vars->phy_flags & PHY_XGXS_FLAG)
4587                 bnx2x_set_master_ln(params);
4588
4589         rc = bnx2x_reset_unicore(params);
4590         /* reset the SerDes and wait for reset bit return low */
4591         if (rc != 0)
4592                 return rc;
4593
4594         bnx2x_set_aer_mmd(params, vars);
4595
4596         /* setting the masterLn_def again after the reset */
4597         if (vars->phy_flags & PHY_XGXS_FLAG) {
4598                 bnx2x_set_master_ln(params);
4599                 bnx2x_set_swap_lanes(params);
4600         }
4601
4602         if (vars->phy_flags & PHY_XGXS_FLAG) {
4603                 if ((params->req_line_speed &&
4604                     ((params->req_line_speed == SPEED_100) ||
4605                      (params->req_line_speed == SPEED_10))) ||
4606                     (!params->req_line_speed &&
4607                      (params->speed_cap_mask >=
4608                        PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
4609                      (params->speed_cap_mask <
4610                        PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
4611                      ))  {
4612                         vars->phy_flags |= PHY_SGMII_FLAG;
4613                 } else {
4614                         vars->phy_flags &= ~PHY_SGMII_FLAG;
4615                 }
4616         }
4617         /* In case of external phy existance, the line speed would be the
4618          line speed linked up by the external phy. In case it is direct only,
4619           then the line_speed during initialization will be equal to the
4620            req_line_speed*/
4621         vars->line_speed = params->req_line_speed;
4622
4623         bnx2x_calc_ieee_aneg_adv(params, &vars->ieee_fc);
4624
4625         /* init ext phy and enable link state int */
4626         non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
4627                        (params->loopback_mode == LOOPBACK_XGXS_10));
4628
4629         if (non_ext_phy ||
4630             (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
4631             (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) ||
4632             (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481) ||
4633             (params->loopback_mode == LOOPBACK_EXT_PHY)) {
4634                 if (params->req_line_speed == SPEED_AUTO_NEG)
4635                         bnx2x_set_parallel_detection(params, vars->phy_flags);
4636                 bnx2x_init_internal_phy(params, vars);
4637         }
4638
4639         if (!non_ext_phy)
4640                 rc |= bnx2x_ext_phy_init(params, vars);
4641
4642         bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4643                      (NIG_STATUS_XGXS0_LINK10G |
4644                       NIG_STATUS_XGXS0_LINK_STATUS |
4645                       NIG_STATUS_SERDES0_LINK_STATUS));
4646
4647         return rc;
4648
4649 }
4650
4651
4652 u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
4653 {
4654         struct bnx2x *bp = params->bp;
4655
4656         u32 val;
4657         DP(NETIF_MSG_LINK, "Phy Initialization started \n");
4658         DP(NETIF_MSG_LINK, "req_speed = %d, req_flowctrl=%d\n",
4659                   params->req_line_speed, params->req_flow_ctrl);
4660         vars->link_status = 0;
4661         vars->phy_link_up = 0;
4662         vars->link_up = 0;
4663         vars->line_speed = 0;
4664         vars->duplex = DUPLEX_FULL;
4665         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4666         vars->mac_type = MAC_TYPE_NONE;
4667
4668         if (params->switch_cfg ==  SWITCH_CFG_1G)
4669                 vars->phy_flags = PHY_SERDES_FLAG;
4670         else
4671                 vars->phy_flags = PHY_XGXS_FLAG;
4672
4673
4674         /* disable attentions */
4675         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
4676                        (NIG_MASK_XGXS0_LINK_STATUS |
4677                         NIG_MASK_XGXS0_LINK10G |
4678                         NIG_MASK_SERDES0_LINK_STATUS |
4679                         NIG_MASK_MI_INT));
4680
4681         bnx2x_emac_init(params, vars);
4682
4683         if (CHIP_REV_IS_FPGA(bp)) {
4684                 vars->link_up = 1;
4685                 vars->line_speed = SPEED_10000;
4686                 vars->duplex = DUPLEX_FULL;
4687                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4688                 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
4689                 /* enable on E1.5 FPGA */
4690                 if (CHIP_IS_E1H(bp)) {
4691                         vars->flow_ctrl |=
4692                                 (BNX2X_FLOW_CTRL_TX | BNX2X_FLOW_CTRL_RX);
4693                         vars->link_status |=
4694                                         (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
4695                                          LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
4696                 }
4697
4698                 bnx2x_emac_enable(params, vars, 0);
4699                 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
4700                 /* disable drain */
4701                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
4702                                     + params->port*4, 0);
4703
4704                 /* update shared memory */
4705                 bnx2x_update_mng(params, vars->link_status);
4706
4707                 return 0;
4708
4709         } else
4710         if (CHIP_REV_IS_EMUL(bp)) {
4711
4712                 vars->link_up = 1;
4713                 vars->line_speed = SPEED_10000;
4714                 vars->duplex = DUPLEX_FULL;
4715                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4716                 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
4717
4718                 bnx2x_bmac_enable(params, vars, 0);
4719
4720                 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
4721                 /* Disable drain */
4722                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
4723                                     + params->port*4, 0);
4724
4725                 /* update shared memory */
4726                 bnx2x_update_mng(params, vars->link_status);
4727
4728                 return 0;
4729
4730         } else
4731         if (params->loopback_mode == LOOPBACK_BMAC) {
4732                 vars->link_up = 1;
4733                 vars->line_speed = SPEED_10000;
4734                 vars->duplex = DUPLEX_FULL;
4735                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4736                 vars->mac_type = MAC_TYPE_BMAC;
4737
4738                 vars->phy_flags = PHY_XGXS_FLAG;
4739
4740                 bnx2x_phy_deassert(params, vars->phy_flags);
4741                 /* set bmac loopback */
4742                 bnx2x_bmac_enable(params, vars, 1);
4743
4744                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4745                     params->port*4, 0);
4746         } else if (params->loopback_mode == LOOPBACK_EMAC) {
4747                 vars->link_up = 1;
4748                 vars->line_speed = SPEED_1000;
4749                 vars->duplex = DUPLEX_FULL;
4750                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4751                 vars->mac_type = MAC_TYPE_EMAC;
4752
4753                 vars->phy_flags = PHY_XGXS_FLAG;
4754
4755                 bnx2x_phy_deassert(params, vars->phy_flags);
4756                 /* set bmac loopback */
4757                 bnx2x_emac_enable(params, vars, 1);
4758                 bnx2x_emac_program(params, vars->line_speed,
4759                                               vars->duplex);
4760                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4761                     params->port*4, 0);
4762         } else if ((params->loopback_mode == LOOPBACK_XGXS_10) ||
4763                   (params->loopback_mode == LOOPBACK_EXT_PHY)) {
4764                 vars->link_up = 1;
4765                 vars->line_speed = SPEED_10000;
4766                 vars->duplex = DUPLEX_FULL;
4767                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4768
4769                 vars->phy_flags = PHY_XGXS_FLAG;
4770
4771                 val = REG_RD(bp,
4772                                  NIG_REG_XGXS0_CTRL_PHY_ADDR+
4773                                  params->port*0x18);
4774                 params->phy_addr = (u8)val;
4775
4776                 bnx2x_phy_deassert(params, vars->phy_flags);
4777                 bnx2x_link_initialize(params, vars);
4778
4779                 vars->mac_type = MAC_TYPE_BMAC;
4780
4781                 bnx2x_bmac_enable(params, vars, 0);
4782
4783                 if (params->loopback_mode == LOOPBACK_XGXS_10) {
4784                         /* set 10G XGXS loopback */
4785                         bnx2x_set_xgxs_loopback(params, vars, 1);
4786                 } else {
4787                         /* set external phy loopback */
4788                         bnx2x_ext_phy_loopback(params);
4789                 }
4790                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4791                             params->port*4, 0);
4792         } else
4793         /* No loopback */
4794         {
4795
4796                 bnx2x_phy_deassert(params, vars->phy_flags);
4797                 switch (params->switch_cfg) {
4798                 case SWITCH_CFG_1G:
4799                         vars->phy_flags |= PHY_SERDES_FLAG;
4800                         if ((params->ext_phy_config &
4801                              PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) ==
4802                              PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482) {
4803                                 vars->phy_flags |=
4804                                         PHY_SGMII_FLAG;
4805                         }
4806
4807                         val = REG_RD(bp,
4808                                          NIG_REG_SERDES0_CTRL_PHY_ADDR+
4809                                          params->port*0x10);
4810
4811                         params->phy_addr = (u8)val;
4812
4813                         break;
4814                 case SWITCH_CFG_10G:
4815                         vars->phy_flags |= PHY_XGXS_FLAG;
4816                         val = REG_RD(bp,
4817                                  NIG_REG_XGXS0_CTRL_PHY_ADDR+
4818                                  params->port*0x18);
4819                         params->phy_addr = (u8)val;
4820
4821                         break;
4822                 default:
4823                         DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
4824                         return -EINVAL;
4825                         break;
4826                 }
4827                 DP(NETIF_MSG_LINK, "Phy address = 0x%x\n", params->phy_addr);
4828
4829                 bnx2x_link_initialize(params, vars);
4830                 msleep(30);
4831                 bnx2x_link_int_enable(params);
4832         }
4833         return 0;
4834 }
4835
4836 static void bnx2x_8726_reset_phy(struct bnx2x *bp, u8 port, u8 ext_phy_addr)
4837 {
4838         DP(NETIF_MSG_LINK, "bnx2x_8726_reset_phy port %d\n", port);
4839
4840         /* Set serial boot control for external load */
4841         bnx2x_cl45_write(bp, port,
4842                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, ext_phy_addr,
4843                        MDIO_PMA_DEVAD,
4844                        MDIO_PMA_REG_GEN_CTRL, 0x0001);
4845
4846         /* Disable Transmitter */
4847         bnx2x_bcm8726_set_transmitter(bp, port, ext_phy_addr, 0);
4848
4849 }
4850
4851 u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
4852                   u8 reset_ext_phy)
4853 {
4854
4855         struct bnx2x *bp = params->bp;
4856         u32 ext_phy_config = params->ext_phy_config;
4857         u16 hw_led_mode = params->hw_led_mode;
4858         u32 chip_id = params->chip_id;
4859         u8 port = params->port;
4860         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
4861         /* disable attentions */
4862
4863         vars->link_status = 0;
4864         bnx2x_update_mng(params, vars->link_status);
4865         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
4866                      (NIG_MASK_XGXS0_LINK_STATUS |
4867                       NIG_MASK_XGXS0_LINK10G |
4868                       NIG_MASK_SERDES0_LINK_STATUS |
4869                       NIG_MASK_MI_INT));
4870
4871         /* activate nig drain */
4872         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
4873
4874         /* disable nig egress interface */
4875         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
4876         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
4877
4878         /* Stop BigMac rx */
4879         bnx2x_bmac_rx_disable(bp, port);
4880
4881         /* disable emac */
4882         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
4883
4884         msleep(10);
4885         /* The PHY reset is controled by GPIO 1
4886          * Hold it as vars low
4887          */
4888          /* clear link led */
4889         bnx2x_set_led(bp, port, LED_MODE_OFF, 0, hw_led_mode, chip_id);
4890         if (reset_ext_phy) {
4891                 switch (ext_phy_type) {
4892                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4893                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4894                         break;
4895                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4896                         DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
4897                                  "low power mode\n",
4898                                  port);
4899                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4900                                           MISC_REGISTERS_GPIO_OUTPUT_LOW,
4901                                           port);
4902                         break;
4903                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
4904                 {
4905                         u8 ext_phy_addr = ((params->ext_phy_config &
4906                                          PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4907                                          PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4908                         /* Set soft reset */
4909                         bnx2x_8726_reset_phy(bp, params->port, ext_phy_addr);
4910                         break;
4911                 }
4912                 default:
4913                         /* HW reset */
4914                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
4915                                           MISC_REGISTERS_GPIO_OUTPUT_LOW,
4916                                           port);
4917                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4918                                           MISC_REGISTERS_GPIO_OUTPUT_LOW,
4919                                           port);
4920                         DP(NETIF_MSG_LINK, "reset external PHY\n");
4921                 }
4922         }
4923         /* reset the SerDes/XGXS */
4924         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
4925                (0x1ff << (port*16)));
4926
4927         /* reset BigMac */
4928         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
4929                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4930
4931         /* disable nig ingress interface */
4932         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
4933         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
4934         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
4935         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
4936         vars->link_up = 0;
4937         return 0;
4938 }
4939
4940 static u8 bnx2x_update_link_down(struct link_params *params,
4941                                struct link_vars *vars)
4942 {
4943         struct bnx2x *bp = params->bp;
4944         u8 port = params->port;
4945         DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
4946         bnx2x_set_led(bp, port, LED_MODE_OFF,
4947                     0, params->hw_led_mode,
4948                     params->chip_id);
4949
4950         /* indicate no mac active */
4951         vars->mac_type = MAC_TYPE_NONE;
4952
4953         /* update shared memory */
4954         vars->link_status = 0;
4955         vars->line_speed = 0;
4956         bnx2x_update_mng(params, vars->link_status);
4957
4958         /* activate nig drain */
4959         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
4960
4961         /* disable emac */
4962         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
4963
4964         msleep(10);
4965
4966         /* reset BigMac */
4967         bnx2x_bmac_rx_disable(bp, params->port);
4968         REG_WR(bp, GRCBASE_MISC +
4969                    MISC_REGISTERS_RESET_REG_2_CLEAR,
4970                    (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4971         return 0;
4972 }
4973
4974 static u8 bnx2x_update_link_up(struct link_params *params,
4975                              struct link_vars *vars,
4976                              u8 link_10g, u32 gp_status)
4977 {
4978         struct bnx2x *bp = params->bp;
4979         u8 port = params->port;
4980         u8 rc = 0;
4981         vars->link_status |= LINK_STATUS_LINK_UP;
4982         if (link_10g) {
4983                 bnx2x_bmac_enable(params, vars, 0);
4984                 bnx2x_set_led(bp, port, LED_MODE_OPER,
4985                             SPEED_10000, params->hw_led_mode,
4986                             params->chip_id);
4987
4988         } else {
4989                 bnx2x_emac_enable(params, vars, 0);
4990                 rc = bnx2x_emac_program(params, vars->line_speed,
4991                                       vars->duplex);
4992
4993                 /* AN complete? */
4994                 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
4995                         if (!(vars->phy_flags &
4996                               PHY_SGMII_FLAG))
4997                                 bnx2x_set_gmii_tx_driver(params);
4998                 }
4999         }
5000
5001         /* PBF - link up */
5002         rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
5003                               vars->line_speed);
5004
5005         /* disable drain */
5006         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
5007
5008         /* update shared memory */
5009         bnx2x_update_mng(params, vars->link_status);
5010         msleep(20);
5011         return rc;
5012 }
5013 /* This function should called upon link interrupt */
5014 /* In case vars->link_up, driver needs to
5015         1. Update the pbf
5016         2. Disable drain
5017         3. Update the shared memory
5018         4. Indicate link up
5019         5. Set LEDs
5020    Otherwise,
5021         1. Update shared memory
5022         2. Reset BigMac
5023         3. Report link down
5024         4. Unset LEDs
5025 */
5026 u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
5027 {
5028         struct bnx2x *bp = params->bp;
5029         u8 port = params->port;
5030         u16 gp_status;
5031         u8 link_10g;
5032         u8 ext_phy_link_up, rc = 0;
5033         u32 ext_phy_type;
5034
5035         DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
5036          port,
5037         (vars->phy_flags & PHY_XGXS_FLAG),
5038          REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
5039
5040         DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
5041         REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
5042         REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
5043         REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
5044
5045         DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
5046           REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
5047           REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
5048
5049         /* disable emac */
5050         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
5051
5052         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
5053
5054         /* Check external link change only for non-direct */
5055         ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars);
5056
5057         /* Read gp_status */
5058         CL45_RD_OVER_CL22(bp, port, params->phy_addr,
5059                               MDIO_REG_BANK_GP_STATUS,
5060                               MDIO_GP_STATUS_TOP_AN_STATUS1,
5061                               &gp_status);
5062
5063         rc = bnx2x_link_settings_status(params, vars, gp_status);
5064         if (rc != 0)
5065                 return rc;
5066
5067         /* anything 10 and over uses the bmac */
5068         link_10g = ((vars->line_speed == SPEED_10000) ||
5069                     (vars->line_speed == SPEED_12000) ||
5070                     (vars->line_speed == SPEED_12500) ||
5071                     (vars->line_speed == SPEED_13000) ||
5072                     (vars->line_speed == SPEED_15000) ||
5073                     (vars->line_speed == SPEED_16000));
5074
5075         bnx2x_link_int_ack(params, vars, link_10g);
5076
5077         /* In case external phy link is up, and internal link is down
5078         ( not initialized yet probably after link initialization, it needs
5079         to be initialized.
5080         Note that after link down-up as result of cable plug,
5081         the xgxs link would probably become up again without the need to
5082         initialize it*/
5083
5084         if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
5085             (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
5086             (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) &&
5087             (ext_phy_link_up && !vars->phy_link_up))
5088                 bnx2x_init_internal_phy(params, vars);
5089
5090         /* link is up only if both local phy and external phy are up */
5091         vars->link_up = (ext_phy_link_up && vars->phy_link_up);
5092
5093         if (vars->link_up)
5094                 rc = bnx2x_update_link_up(params, vars, link_10g, gp_status);
5095         else
5096                 rc = bnx2x_update_link_down(params, vars);
5097
5098         return rc;
5099 }
5100
5101 static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
5102 {
5103         u8 ext_phy_addr[PORT_MAX];
5104         u16 val;
5105         s8 port;
5106
5107         /* PART1 - Reset both phys */
5108         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
5109                 /* Extract the ext phy address for the port */
5110                 u32 ext_phy_config = REG_RD(bp, shmem_base +
5111                                         offsetof(struct shmem_region,
5112                    dev_info.port_hw_config[port].external_phy_config));
5113
5114                 /* disable attentions */
5115                 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
5116                              (NIG_MASK_XGXS0_LINK_STATUS |
5117                               NIG_MASK_XGXS0_LINK10G |
5118                               NIG_MASK_SERDES0_LINK_STATUS |
5119                               NIG_MASK_MI_INT));
5120
5121                 ext_phy_addr[port] =
5122                         ((ext_phy_config &
5123                               PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
5124                               PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
5125
5126                 /* Need to take the phy out of low power mode in order
5127                         to write to access its registers */
5128                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5129                                   MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
5130
5131                 /* Reset the phy */
5132                 bnx2x_cl45_write(bp, port,
5133                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5134                                ext_phy_addr[port],
5135                                MDIO_PMA_DEVAD,
5136                                MDIO_PMA_REG_CTRL,
5137                                1<<15);
5138         }
5139
5140         /* Add delay of 150ms after reset */
5141         msleep(150);
5142
5143         /* PART2 - Download firmware to both phys */
5144         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
5145                 u16 fw_ver1;
5146
5147                 bnx2x_bcm8073_external_rom_boot(bp, port,
5148                                               ext_phy_addr[port], shmem_base);
5149
5150                 bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5151                               ext_phy_addr[port],
5152                               MDIO_PMA_DEVAD,
5153                               MDIO_PMA_REG_ROM_VER1, &fw_ver1);
5154                 if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
5155                         DP(NETIF_MSG_LINK,
5156                                  "bnx2x_8073_common_init_phy port %x:"
5157                                  "Download failed. fw version = 0x%x\n",
5158                                  port, fw_ver1);
5159                         return -EINVAL;
5160                 }
5161
5162                 /* Only set bit 10 = 1 (Tx power down) */
5163                 bnx2x_cl45_read(bp, port,
5164                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5165                               ext_phy_addr[port],
5166                               MDIO_PMA_DEVAD,
5167                               MDIO_PMA_REG_TX_POWER_DOWN, &val);
5168
5169                 /* Phase1 of TX_POWER_DOWN reset */
5170                 bnx2x_cl45_write(bp, port,
5171                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5172                                ext_phy_addr[port],
5173                                MDIO_PMA_DEVAD,
5174                                MDIO_PMA_REG_TX_POWER_DOWN,
5175                                (val | 1<<10));
5176         }
5177
5178         /* Toggle Transmitter: Power down and then up with 600ms
5179            delay between */
5180         msleep(600);
5181
5182         /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
5183         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
5184                 /* Phase2 of POWER_DOWN_RESET */
5185                 /* Release bit 10 (Release Tx power down) */
5186                 bnx2x_cl45_read(bp, port,
5187                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5188                               ext_phy_addr[port],
5189                               MDIO_PMA_DEVAD,
5190                               MDIO_PMA_REG_TX_POWER_DOWN, &val);
5191
5192                 bnx2x_cl45_write(bp, port,
5193                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5194                                ext_phy_addr[port],
5195                                MDIO_PMA_DEVAD,
5196                                MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
5197                 msleep(15);
5198
5199                 /* Read modify write the SPI-ROM version select register */
5200                 bnx2x_cl45_read(bp, port,
5201                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5202                               ext_phy_addr[port],
5203                               MDIO_PMA_DEVAD,
5204                               MDIO_PMA_REG_EDC_FFE_MAIN, &val);
5205                 bnx2x_cl45_write(bp, port,
5206                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5207                               ext_phy_addr[port],
5208                               MDIO_PMA_DEVAD,
5209                               MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
5210
5211                 /* set GPIO2 back to LOW */
5212                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5213                                   MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
5214         }
5215         return 0;
5216
5217 }
5218
5219
5220 static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base)
5221 {
5222         u8 ext_phy_addr;
5223         u32 val;
5224         s8 port;
5225         /* Use port1 because of the static port-swap */
5226         /* Enable the module detection interrupt */
5227         val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
5228         val |= ((1<<MISC_REGISTERS_GPIO_3)|
5229                 (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
5230         REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
5231
5232         bnx2x_hw_reset(bp, 1);
5233         msleep(5);
5234         for (port = 0; port < PORT_MAX; port++) {
5235                 /* Extract the ext phy address for the port */
5236                 u32 ext_phy_config = REG_RD(bp, shmem_base +
5237                                         offsetof(struct shmem_region,
5238                         dev_info.port_hw_config[port].external_phy_config));
5239
5240                 ext_phy_addr =
5241                         ((ext_phy_config &
5242                               PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
5243                               PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
5244                 DP(NETIF_MSG_LINK, "8726_common_init : ext_phy_addr = 0x%x\n",
5245                          ext_phy_addr);
5246
5247                 bnx2x_8726_reset_phy(bp, port, ext_phy_addr);
5248
5249                 /* Set fault module detected LED on */
5250                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
5251                                   MISC_REGISTERS_GPIO_HIGH,
5252                                   port);
5253         }
5254
5255         return 0;
5256 }
5257
5258 u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
5259 {
5260         u8 rc = 0;
5261         u32 ext_phy_type;
5262
5263         DP(NETIF_MSG_LINK, "Begin common phy init\n");
5264
5265         /* Read the ext_phy_type for arbitrary port(0) */
5266         ext_phy_type = XGXS_EXT_PHY_TYPE(
5267                         REG_RD(bp, shmem_base +
5268                            offsetof(struct shmem_region,
5269                              dev_info.port_hw_config[0].external_phy_config)));
5270
5271         switch (ext_phy_type) {
5272         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
5273         {
5274                 rc = bnx2x_8073_common_init_phy(bp, shmem_base);
5275                 break;
5276         }
5277         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
5278                 /* GPIO1 affects both ports, so there's need to pull
5279                 it for single port alone */
5280                 rc = bnx2x_8726_common_init_phy(bp, shmem_base);
5281
5282                 break;
5283         default:
5284                 DP(NETIF_MSG_LINK,
5285                          "bnx2x_common_init_phy: ext_phy 0x%x not required\n",
5286                          ext_phy_type);
5287                 break;
5288         }
5289
5290         return rc;
5291 }
5292
5293
5294
5295 static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
5296 {
5297         u16 val, cnt;
5298
5299         bnx2x_cl45_read(bp, port,
5300                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5301                       phy_addr,
5302                       MDIO_PMA_DEVAD,
5303                       MDIO_PMA_REG_7101_RESET, &val);
5304
5305         for (cnt = 0; cnt < 10; cnt++) {
5306                 msleep(50);
5307                 /* Writes a self-clearing reset */
5308                 bnx2x_cl45_write(bp, port,
5309                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5310                                phy_addr,
5311                                MDIO_PMA_DEVAD,
5312                                MDIO_PMA_REG_7101_RESET,
5313                                (val | (1<<15)));
5314                 /* Wait for clear */
5315                 bnx2x_cl45_read(bp, port,
5316                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5317                               phy_addr,
5318                               MDIO_PMA_DEVAD,
5319                               MDIO_PMA_REG_7101_RESET, &val);
5320
5321                 if ((val & (1<<15)) == 0)
5322                         break;
5323         }
5324 }
5325 #define RESERVED_SIZE 256
5326 /* max application is 160K bytes - data at end of RAM */
5327 #define MAX_APP_SIZE (160*1024 - RESERVED_SIZE)
5328
5329 /* Header is 14 bytes */
5330 #define HEADER_SIZE 14
5331 #define DATA_OFFSET HEADER_SIZE
5332
5333 #define SPI_START_TRANSFER(bp, port, ext_phy_addr) \
5334         bnx2x_cl45_write(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, \
5335                         ext_phy_addr, \
5336                         MDIO_PCS_DEVAD, \
5337                         MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 1)
5338
5339 /* Programs an image to DSP's flash via the SPI port*/
5340 static u8 bnx2x_sfx7101_flash_download(struct bnx2x *bp, u8 port,
5341                                      u8 ext_phy_addr,
5342                                      char data[], u32 size)
5343 {
5344         const u16 num_trans = size/4; /* 4 bytes can be sent at a time */
5345         /* Doesn't include last trans!*/
5346         const u16 last_trans_size = size%4; /* Num bytes on last trans */
5347         u16 trans_cnt, byte_cnt;
5348         u32 data_index;
5349         u16 tmp;
5350         u16 code_started = 0;
5351         u16 image_revision1, image_revision2;
5352         u16 cnt;
5353
5354         DP(NETIF_MSG_LINK, "bnx2x_sfx7101_flash_download file_size=%d\n", size);
5355         /* Going to flash*/
5356         if ((size-HEADER_SIZE) > MAX_APP_SIZE) {
5357                 /* This very often will be the case, because the image is built
5358                 with 160Kbytes size whereas the total image size must actually
5359                 be 160Kbytes-RESERVED_SIZE */
5360                 DP(NETIF_MSG_LINK, "Warning, file size was %d bytes "
5361                          "truncated to %d bytes\n", size, MAX_APP_SIZE);
5362                 size = MAX_APP_SIZE+HEADER_SIZE;
5363         }
5364         DP(NETIF_MSG_LINK, "File version is %c%c\n", data[0x14e], data[0x14f]);
5365         DP(NETIF_MSG_LINK, "          %c%c\n", data[0x150], data[0x151]);
5366         /* Put the DSP in download mode by setting FLASH_CFG[2] to 1
5367            and issuing a reset.*/
5368
5369         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
5370                           MISC_REGISTERS_GPIO_HIGH, port);
5371
5372         bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
5373
5374         /* wait 0.5 sec */
5375         for (cnt = 0; cnt < 100; cnt++)
5376                 msleep(5);
5377
5378         /* Make sure we can access the DSP
5379            And it's in the correct mode (waiting for download) */
5380
5381         bnx2x_cl45_read(bp, port,
5382                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5383                       ext_phy_addr,
5384                       MDIO_PCS_DEVAD,
5385                       MDIO_PCS_REG_7101_DSP_ACCESS, &tmp);
5386
5387         if (tmp != 0x000A) {
5388                 DP(NETIF_MSG_LINK, "DSP is not in waiting on download mode. "
5389                          "Expected 0x000A, read 0x%04X\n", tmp);
5390                 DP(NETIF_MSG_LINK, "Download failed\n");
5391                 return -EINVAL;
5392         }
5393
5394         /* Mux the SPI interface away from the internal processor */
5395         bnx2x_cl45_write(bp, port,
5396                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5397                        ext_phy_addr,
5398                        MDIO_PCS_DEVAD,
5399                        MDIO_PCS_REG_7101_SPI_MUX, 1);
5400
5401         /* Reset the SPI port */
5402         bnx2x_cl45_write(bp, port,
5403                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5404                        ext_phy_addr,
5405                        MDIO_PCS_DEVAD,
5406                        MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
5407         bnx2x_cl45_write(bp, port,
5408                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5409                        ext_phy_addr,
5410                        MDIO_PCS_DEVAD,
5411                        MDIO_PCS_REG_7101_SPI_CTRL_ADDR,
5412                        (1<<MDIO_PCS_REG_7101_SPI_RESET_BIT));
5413         bnx2x_cl45_write(bp, port,
5414                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5415                        ext_phy_addr,
5416                        MDIO_PCS_DEVAD,
5417                        MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
5418
5419         /* Erase the flash */
5420         bnx2x_cl45_write(bp, port,
5421                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5422                        ext_phy_addr,
5423                        MDIO_PCS_DEVAD,
5424                        MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5425                        MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
5426
5427         bnx2x_cl45_write(bp, port,
5428                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5429                        ext_phy_addr,
5430                        MDIO_PCS_DEVAD,
5431                        MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5432                        1);
5433
5434         SPI_START_TRANSFER(bp, port, ext_phy_addr);
5435         bnx2x_cl45_write(bp, port,
5436                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5437                        ext_phy_addr,
5438                        MDIO_PCS_DEVAD,
5439                        MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5440                        MDIO_PCS_REG_7101_SPI_FIFO_ADDR_BULK_ERASE_CMD);
5441
5442         bnx2x_cl45_write(bp, port,
5443                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5444                        ext_phy_addr,
5445                        MDIO_PCS_DEVAD,
5446                        MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5447                        1);
5448         SPI_START_TRANSFER(bp, port, ext_phy_addr);
5449
5450         /* Wait 10 seconds, the maximum time for the erase to complete */
5451         DP(NETIF_MSG_LINK, "Erasing flash, this takes 10 seconds...\n");
5452         for (cnt = 0; cnt < 1000; cnt++)
5453                 msleep(10);
5454
5455         DP(NETIF_MSG_LINK, "Downloading flash, please wait...\n");
5456         data_index = 0;
5457         for (trans_cnt = 0; trans_cnt < num_trans; trans_cnt++) {
5458                 bnx2x_cl45_write(bp, port,
5459                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5460                              ext_phy_addr,
5461                              MDIO_PCS_DEVAD,
5462                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5463                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
5464
5465                 bnx2x_cl45_write(bp, port,
5466                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5467                                ext_phy_addr,
5468                                MDIO_PCS_DEVAD,
5469                                MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5470                                1);
5471                 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5472
5473                 bnx2x_cl45_write(bp, port,
5474                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5475                                ext_phy_addr,
5476                                MDIO_PCS_DEVAD,
5477                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5478                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
5479
5480                 /* Bits 23-16 of address */
5481                 bnx2x_cl45_write(bp, port,
5482                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5483                                ext_phy_addr,
5484                                MDIO_PCS_DEVAD,
5485                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5486                                (data_index>>16));
5487                 /* Bits 15-8 of address */
5488                 bnx2x_cl45_write(bp, port,
5489                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5490                                ext_phy_addr,
5491                                MDIO_PCS_DEVAD,
5492                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5493                                (data_index>>8));
5494
5495                 /* Bits 7-0 of address */
5496                 bnx2x_cl45_write(bp, port,
5497                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5498                                ext_phy_addr,
5499                                MDIO_PCS_DEVAD,
5500                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5501                                ((u16)data_index));
5502
5503                 byte_cnt = 0;
5504                 while (byte_cnt < 4 && data_index < size) {
5505                         bnx2x_cl45_write(bp, port,
5506                                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5507                                        ext_phy_addr,
5508                                MDIO_PCS_DEVAD,
5509                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5510                                data[data_index++]);
5511                         byte_cnt++;
5512                 }
5513
5514                 bnx2x_cl45_write(bp, port,
5515                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5516                                ext_phy_addr,
5517                                MDIO_PCS_DEVAD,
5518                                MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5519                                byte_cnt+4);
5520
5521                 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5522                 msleep(5); /* Wait 5 ms minimum between transs */
5523
5524                 /* Let the user know something's going on.*/
5525                 /* a pacifier ever 4K */
5526                 if ((data_index % 1023) == 0)
5527                         DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
5528         }
5529
5530         DP(NETIF_MSG_LINK, "\n");
5531         /* Transfer the last block if there is data remaining */
5532         if (last_trans_size) {
5533                 bnx2x_cl45_write(bp, port,
5534                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5535                         ext_phy_addr,
5536                         MDIO_PCS_DEVAD,
5537                         MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5538                         MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
5539
5540                 bnx2x_cl45_write(bp, port,
5541                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5542                                ext_phy_addr,
5543                                MDIO_PCS_DEVAD,
5544                                MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5545                                1);
5546
5547                 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5548
5549                 bnx2x_cl45_write(bp, port,
5550                              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5551                              ext_phy_addr,
5552                              MDIO_PCS_DEVAD,
5553                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5554                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
5555
5556                 /* Bits 23-16 of address */
5557                 bnx2x_cl45_write(bp, port,
5558                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5559                                ext_phy_addr,
5560                                MDIO_PCS_DEVAD,
5561                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5562                                (data_index>>16));
5563                 /* Bits 15-8 of address */
5564                 bnx2x_cl45_write(bp, port,
5565                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5566                                ext_phy_addr,
5567                                MDIO_PCS_DEVAD,
5568                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5569                                (data_index>>8));
5570
5571                 /* Bits 7-0 of address */
5572                 bnx2x_cl45_write(bp, port,
5573                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5574                                ext_phy_addr,
5575                                MDIO_PCS_DEVAD,
5576                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5577                                ((u16)data_index));
5578
5579                 byte_cnt = 0;
5580                 while (byte_cnt < last_trans_size && data_index < size) {
5581                         /* Bits 7-0 of address */
5582                         bnx2x_cl45_write(bp, port,
5583                                 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5584                                 ext_phy_addr,
5585                                 MDIO_PCS_DEVAD,
5586                                 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5587                                 data[data_index++]);
5588                         byte_cnt++;
5589                 }
5590
5591                 bnx2x_cl45_write(bp, port,
5592                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5593                                ext_phy_addr,
5594                                MDIO_PCS_DEVAD,
5595                                MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5596                                byte_cnt+4);
5597
5598                 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5599         }
5600
5601         /* DSP Remove Download Mode */
5602         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
5603                           MISC_REGISTERS_GPIO_LOW, port);
5604
5605         bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
5606
5607         /* wait 0.5 sec to allow it to run */
5608         for (cnt = 0; cnt < 100; cnt++)
5609                 msleep(5);
5610
5611         bnx2x_hw_reset(bp, port);
5612
5613         for (cnt = 0; cnt < 100; cnt++)
5614                 msleep(5);
5615
5616         /* Check that the code is started. In case the download
5617         checksum failed, the code won't be started. */
5618         bnx2x_cl45_read(bp, port,
5619                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5620                       ext_phy_addr,
5621                       MDIO_PCS_DEVAD,
5622                       MDIO_PCS_REG_7101_DSP_ACCESS,
5623                       &tmp);
5624
5625         code_started = (tmp & (1<<4));
5626         if (!code_started) {
5627                 DP(NETIF_MSG_LINK, "Download failed. Please check file.\n");
5628                 return -EINVAL;
5629         }
5630
5631         /* Verify that the file revision is now equal to the image
5632         revision within the DSP */
5633         bnx2x_cl45_read(bp, port,
5634                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5635                       ext_phy_addr,
5636                       MDIO_PMA_DEVAD,
5637                       MDIO_PMA_REG_7101_VER1,
5638                       &image_revision1);
5639
5640         bnx2x_cl45_read(bp, port,
5641                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5642                       ext_phy_addr,
5643                       MDIO_PMA_DEVAD,
5644                       MDIO_PMA_REG_7101_VER2,
5645                       &image_revision2);
5646
5647         if (data[0x14e] != (image_revision2&0xFF) ||
5648             data[0x14f] != ((image_revision2&0xFF00)>>8) ||
5649             data[0x150] != (image_revision1&0xFF) ||
5650             data[0x151] != ((image_revision1&0xFF00)>>8)) {
5651                 DP(NETIF_MSG_LINK, "Download failed.\n");
5652                 return -EINVAL;
5653         }
5654         DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
5655         return 0;
5656 }
5657
5658 u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
5659                       u8 driver_loaded, char data[], u32 size)
5660 {
5661         u8 rc = 0;
5662         u32 ext_phy_type;
5663         u8 ext_phy_addr;
5664         ext_phy_addr = ((ext_phy_config &
5665                         PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
5666                         PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
5667
5668         ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
5669
5670         switch (ext_phy_type) {
5671         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
5672         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
5673         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
5674         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
5675                 DP(NETIF_MSG_LINK,
5676                         "Flash download not supported for this ext phy\n");
5677                 rc = -EINVAL;
5678                 break;
5679         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
5680                 /* Take ext phy out of reset */
5681                 if (!driver_loaded)
5682                         bnx2x_turn_on_ef(bp, port, ext_phy_addr, ext_phy_type);
5683                 rc = bnx2x_sfx7101_flash_download(bp, port, ext_phy_addr,
5684                                                 data, size);
5685                 if (!driver_loaded)
5686                         bnx2x_turn_off_sf(bp, port);
5687                 break;
5688         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
5689         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
5690         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
5691         default:
5692                 DP(NETIF_MSG_LINK, "Invalid ext phy type\n");
5693                 rc = -EINVAL;
5694                 break;
5695         }
5696         return rc;
5697 }
5698