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