]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/net/bnx2x_link.c
bnx2x: Change GPIO for any port
[linux-2.6-omap-h63xx.git] / drivers / net / bnx2x_link.c
1 /* Copyright 2008 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 #include <linux/version.h>
25
26 #include "bnx2x_reg.h"
27 #include "bnx2x_fw_defs.h"
28 #include "bnx2x_hsi.h"
29 #include "bnx2x_link.h"
30 #include "bnx2x.h"
31
32 /********************************************************/
33 #define SUPPORT_CL73 0 /* Currently no */
34 #define ETH_HLEN                        14
35 #define ETH_OVREHEAD            (ETH_HLEN + 8)/* 8 for CRC + VLAN*/
36 #define ETH_MIN_PACKET_SIZE             60
37 #define ETH_MAX_PACKET_SIZE             1500
38 #define ETH_MAX_JUMBO_PACKET_SIZE       9600
39 #define MDIO_ACCESS_TIMEOUT             1000
40 #define BMAC_CONTROL_RX_ENABLE  2
41
42 /***********************************************************/
43 /*                       Shortcut definitions              */
44 /***********************************************************/
45
46 #define NIG_STATUS_XGXS0_LINK10G \
47                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
48 #define NIG_STATUS_XGXS0_LINK_STATUS \
49                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
50 #define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
51                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
52 #define NIG_STATUS_SERDES0_LINK_STATUS \
53                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
54 #define NIG_MASK_MI_INT \
55                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
56 #define NIG_MASK_XGXS0_LINK10G \
57                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
58 #define NIG_MASK_XGXS0_LINK_STATUS \
59                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
60 #define NIG_MASK_SERDES0_LINK_STATUS \
61                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
62
63 #define MDIO_AN_CL73_OR_37_COMPLETE \
64                 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
65                  MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
66
67 #define XGXS_RESET_BITS \
68         (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW |   \
69          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ |      \
70          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN |    \
71          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
72          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
73
74 #define SERDES_RESET_BITS \
75         (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
76          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ |    \
77          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN |  \
78          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
79
80 #define AUTONEG_CL37            SHARED_HW_CFG_AN_ENABLE_CL37
81 #define AUTONEG_CL73            SHARED_HW_CFG_AN_ENABLE_CL73
82 #define AUTONEG_BAM                     SHARED_HW_CFG_AN_ENABLE_BAM
83 #define AUTONEG_PARALLEL                \
84                                 SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
85 #define AUTONEG_SGMII_FIBER_AUTODET     \
86                                 SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
87 #define AUTONEG_REMOTE_PHY              SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
88
89 #define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
90                         MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
91 #define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
92                         MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
93 #define GP_STATUS_SPEED_MASK \
94                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
95 #define GP_STATUS_10M   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
96 #define GP_STATUS_100M  MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
97 #define GP_STATUS_1G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
98 #define GP_STATUS_2_5G  MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
99 #define GP_STATUS_5G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
100 #define GP_STATUS_6G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
101 #define GP_STATUS_10G_HIG \
102                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
103 #define GP_STATUS_10G_CX4 \
104                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
105 #define GP_STATUS_12G_HIG \
106                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG
107 #define GP_STATUS_12_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G
108 #define GP_STATUS_13G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G
109 #define GP_STATUS_15G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G
110 #define GP_STATUS_16G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G
111 #define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
112 #define GP_STATUS_10G_KX4 \
113                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
114
115 #define LINK_10THD                      LINK_STATUS_SPEED_AND_DUPLEX_10THD
116 #define LINK_10TFD                      LINK_STATUS_SPEED_AND_DUPLEX_10TFD
117 #define LINK_100TXHD            LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
118 #define LINK_100T4                      LINK_STATUS_SPEED_AND_DUPLEX_100T4
119 #define LINK_100TXFD            LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
120 #define LINK_1000THD            LINK_STATUS_SPEED_AND_DUPLEX_1000THD
121 #define LINK_1000TFD            LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
122 #define LINK_1000XFD            LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
123 #define LINK_2500THD            LINK_STATUS_SPEED_AND_DUPLEX_2500THD
124 #define LINK_2500TFD            LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
125 #define LINK_2500XFD            LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
126 #define LINK_10GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
127 #define LINK_10GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
128 #define LINK_12GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_12GTFD
129 #define LINK_12GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_12GXFD
130 #define LINK_12_5GTFD           LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD
131 #define LINK_12_5GXFD           LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD
132 #define LINK_13GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_13GTFD
133 #define LINK_13GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_13GXFD
134 #define LINK_15GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_15GTFD
135 #define LINK_15GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_15GXFD
136 #define LINK_16GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_16GTFD
137 #define LINK_16GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_16GXFD
138
139 #define PHY_XGXS_FLAG                   0x1
140 #define PHY_SGMII_FLAG                  0x2
141 #define PHY_SERDES_FLAG                 0x4
142
143 /**********************************************************/
144 /*                     INTERFACE                          */
145 /**********************************************************/
146 #define CL45_WR_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
147         bnx2x_cl45_write(_bp, _port, 0, _phy_addr, \
148                 DEFAULT_PHY_DEV_ADDR, \
149                 (_bank + (_addr & 0xf)), \
150                 _val)
151
152 #define CL45_RD_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
153         bnx2x_cl45_read(_bp, _port, 0, _phy_addr, \
154                 DEFAULT_PHY_DEV_ADDR, \
155                 (_bank + (_addr & 0xf)), \
156                 _val)
157
158 static void bnx2x_set_phy_mdio(struct link_params *params)
159 {
160         struct bnx2x *bp = params->bp;
161         REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
162                    params->port*0x18, 0);
163         REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
164                    DEFAULT_PHY_DEV_ADDR);
165 }
166
167 static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
168 {
169         u32 val = REG_RD(bp, reg);
170
171         val |= bits;
172         REG_WR(bp, reg, val);
173         return val;
174 }
175
176 static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
177 {
178         u32 val = REG_RD(bp, reg);
179
180         val &= ~bits;
181         REG_WR(bp, reg, val);
182         return val;
183 }
184
185 static void bnx2x_emac_init(struct link_params *params,
186                            struct link_vars *vars)
187 {
188         /* reset and unreset the emac core */
189         struct bnx2x *bp = params->bp;
190         u8 port = params->port;
191         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
192         u32 val;
193         u16 timeout;
194
195         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
196                    (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
197         udelay(5);
198         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
199                    (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
200
201         /* init emac - use read-modify-write */
202         /* self clear reset */
203         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
204         EMAC_WR(EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
205
206         timeout = 200;
207         do
208         {
209                 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
210                 DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
211                 if (!timeout) {
212                         DP(NETIF_MSG_LINK, "EMAC timeout!\n");
213                         return;
214                 }
215                 timeout--;
216         }while (val & EMAC_MODE_RESET);
217
218         /* Set mac address */
219         val = ((params->mac_addr[0] << 8) |
220                 params->mac_addr[1]);
221         EMAC_WR(EMAC_REG_EMAC_MAC_MATCH, val);
222
223         val = ((params->mac_addr[2] << 24) |
224                (params->mac_addr[3] << 16) |
225                (params->mac_addr[4] << 8) |
226                 params->mac_addr[5]);
227         EMAC_WR(EMAC_REG_EMAC_MAC_MATCH + 4, val);
228 }
229
230 static u8 bnx2x_emac_enable(struct link_params *params,
231                           struct link_vars *vars, u8 lb)
232 {
233         struct bnx2x *bp = params->bp;
234         u8 port = params->port;
235         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
236         u32 val;
237
238         DP(NETIF_MSG_LINK, "enabling EMAC\n");
239
240         /* enable emac and not bmac */
241         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
242
243         /* for paladium */
244         if (CHIP_REV_IS_EMUL(bp)) {
245                 /* Use lane 1 (of lanes 0-3) */
246                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
247                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
248                             port*4, 1);
249         }
250         /* for fpga */
251         else
252
253         if (CHIP_REV_IS_FPGA(bp)) {
254                 /* Use lane 1 (of lanes 0-3) */
255                 DP(NETIF_MSG_LINK, "bnx2x_emac_enable: Setting FPGA\n");
256
257                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
258                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4,
259                             0);
260         } else
261         /* ASIC */
262         if (vars->phy_flags & PHY_XGXS_FLAG) {
263                 u32 ser_lane = ((params->lane_config &
264                             PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
265                             PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
266
267                 DP(NETIF_MSG_LINK, "XGXS\n");
268                 /* select the master lanes (out of 0-3) */
269                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 +
270                            port*4, ser_lane);
271                 /* select XGXS */
272                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
273                            port*4, 1);
274
275         } else { /* SerDes */
276                 DP(NETIF_MSG_LINK, "SerDes\n");
277                 /* select SerDes */
278                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
279                            port*4, 0);
280         }
281
282         /* enable emac */
283         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
284
285         if (CHIP_REV_IS_SLOW(bp)) {
286                 /* config GMII mode */
287                 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
288                 EMAC_WR(EMAC_REG_EMAC_MODE,
289                             (val | EMAC_MODE_PORT_GMII));
290         } else { /* ASIC */
291                 /* pause enable/disable */
292                 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
293                                EMAC_RX_MODE_FLOW_EN);
294                 if (vars->flow_ctrl & FLOW_CTRL_RX)
295                         bnx2x_bits_en(bp, emac_base +
296                                     EMAC_REG_EMAC_RX_MODE,
297                                     EMAC_RX_MODE_FLOW_EN);
298
299                 bnx2x_bits_dis(bp,  emac_base + EMAC_REG_EMAC_TX_MODE,
300                              (EMAC_TX_MODE_EXT_PAUSE_EN |
301                               EMAC_TX_MODE_FLOW_EN));
302                 if (vars->flow_ctrl & FLOW_CTRL_TX)
303                         bnx2x_bits_en(bp, emac_base +
304                                     EMAC_REG_EMAC_TX_MODE,
305                                    (EMAC_TX_MODE_EXT_PAUSE_EN |
306                                     EMAC_TX_MODE_FLOW_EN));
307         }
308
309         /* KEEP_VLAN_TAG, promiscuous */
310         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
311         val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
312         EMAC_WR(EMAC_REG_EMAC_RX_MODE, val);
313
314         /* Set Loopback */
315         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
316         if (lb)
317                 val |= 0x810;
318         else
319                 val &= ~0x810;
320         EMAC_WR(EMAC_REG_EMAC_MODE, val);
321
322         /* enable emac for jumbo packets */
323         EMAC_WR(EMAC_REG_EMAC_RX_MTU_SIZE,
324                 (EMAC_RX_MTU_SIZE_JUMBO_ENA |
325                  (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
326
327         /* strip CRC */
328         REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
329
330         /* disable the NIG in/out to the bmac */
331         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
332         REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
333         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
334
335         /* enable the NIG in/out to the emac */
336         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
337         val = 0;
338         if (vars->flow_ctrl & FLOW_CTRL_TX)
339                 val = 1;
340
341         REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
342         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
343
344         if (CHIP_REV_IS_EMUL(bp)) {
345                 /* take the BigMac out of reset */
346                 REG_WR(bp,
347                            GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
348                            (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
349
350                 /* enable access for bmac registers */
351                 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
352         }
353
354         vars->mac_type = MAC_TYPE_EMAC;
355         return 0;
356 }
357
358
359
360 static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
361                           u8 is_lb)
362 {
363         struct bnx2x *bp = params->bp;
364         u8 port = params->port;
365         u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
366                                NIG_REG_INGRESS_BMAC0_MEM;
367         u32 wb_data[2];
368         u32 val;
369
370         DP(NETIF_MSG_LINK, "Enabling BigMAC\n");
371         /* reset and unreset the BigMac */
372         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
373                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
374         msleep(1);
375
376         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
377                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
378
379         /* enable access for bmac registers */
380         REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
381
382         /* XGXS control */
383         wb_data[0] = 0x3c;
384         wb_data[1] = 0;
385         REG_WR_DMAE(bp, bmac_addr +
386                       BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
387                       wb_data, 2);
388
389         /* tx MAC SA */
390         wb_data[0] = ((params->mac_addr[2] << 24) |
391                        (params->mac_addr[3] << 16) |
392                        (params->mac_addr[4] << 8) |
393                         params->mac_addr[5]);
394         wb_data[1] = ((params->mac_addr[0] << 8) |
395                         params->mac_addr[1]);
396         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR,
397                     wb_data, 2);
398
399         /* tx control */
400         val = 0xc0;
401         if (vars->flow_ctrl & FLOW_CTRL_TX)
402                 val |= 0x800000;
403         wb_data[0] = val;
404         wb_data[1] = 0;
405         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL,
406                         wb_data, 2);
407
408         /* mac control */
409         val = 0x3;
410         if (is_lb) {
411                 val |= 0x4;
412                 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
413         }
414         wb_data[0] = val;
415         wb_data[1] = 0;
416         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
417                     wb_data, 2);
418
419
420         /* set rx mtu */
421         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
422         wb_data[1] = 0;
423         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE,
424                         wb_data, 2);
425
426         /* rx control set to don't strip crc */
427         val = 0x14;
428         if (vars->flow_ctrl & FLOW_CTRL_RX)
429                 val |= 0x20;
430         wb_data[0] = val;
431         wb_data[1] = 0;
432         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL,
433                         wb_data, 2);
434
435         /* set tx mtu */
436         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
437         wb_data[1] = 0;
438         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE,
439                         wb_data, 2);
440
441         /* set cnt max size */
442         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
443         wb_data[1] = 0;
444         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE,
445                     wb_data, 2);
446
447         /* configure safc */
448         wb_data[0] = 0x1000200;
449         wb_data[1] = 0;
450         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
451                     wb_data, 2);
452         /* fix for emulation */
453         if (CHIP_REV_IS_EMUL(bp)) {
454                 wb_data[0] = 0xf000;
455                 wb_data[1] = 0;
456                 REG_WR_DMAE(bp,
457                             bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
458                             wb_data, 2);
459         }
460
461         REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
462         REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
463         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
464         val = 0;
465         if (vars->flow_ctrl & FLOW_CTRL_TX)
466                 val = 1;
467         REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
468         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
469         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
470         REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
471         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
472         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
473
474         vars->mac_type = MAC_TYPE_BMAC;
475         return 0;
476 }
477
478 static void bnx2x_phy_deassert(struct link_params *params, u8 phy_flags)
479 {
480         struct bnx2x *bp = params->bp;
481         u32 val;
482
483         if (phy_flags & PHY_XGXS_FLAG) {
484                 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:XGXS\n");
485                 val = XGXS_RESET_BITS;
486
487         } else { /* SerDes */
488                 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:SerDes\n");
489                 val = SERDES_RESET_BITS;
490         }
491
492         val = val << (params->port*16);
493
494         /* reset and unreset the SerDes/XGXS */
495         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
496                     val);
497         udelay(500);
498         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET,
499                     val);
500         bnx2x_set_phy_mdio(params);
501 }
502
503 void bnx2x_link_status_update(struct link_params *params,
504                             struct link_vars   *vars)
505 {
506         struct bnx2x *bp = params->bp;
507         u8 link_10g;
508         u8 port = params->port;
509
510         if (params->switch_cfg ==  SWITCH_CFG_1G)
511                 vars->phy_flags = PHY_SERDES_FLAG;
512         else
513                 vars->phy_flags = PHY_XGXS_FLAG;
514         vars->link_status = REG_RD(bp, params->shmem_base +
515                                           offsetof(struct shmem_region,
516                                            port_mb[port].link_status));
517
518         vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
519
520         if (vars->link_up) {
521                 DP(NETIF_MSG_LINK, "phy link up\n");
522
523                 vars->phy_link_up = 1;
524                 vars->duplex = DUPLEX_FULL;
525                 switch (vars->link_status &
526                                         LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
527                         case LINK_10THD:
528                                 vars->duplex = DUPLEX_HALF;
529                                 /* fall thru */
530                         case LINK_10TFD:
531                                 vars->line_speed = SPEED_10;
532                                 break;
533
534                         case LINK_100TXHD:
535                                 vars->duplex = DUPLEX_HALF;
536                                 /* fall thru */
537                         case LINK_100T4:
538                         case LINK_100TXFD:
539                                 vars->line_speed = SPEED_100;
540                                 break;
541
542                         case LINK_1000THD:
543                                 vars->duplex = DUPLEX_HALF;
544                                 /* fall thru */
545                         case LINK_1000TFD:
546                                 vars->line_speed = SPEED_1000;
547                                 break;
548
549                         case LINK_2500THD:
550                                 vars->duplex = DUPLEX_HALF;
551                                 /* fall thru */
552                         case LINK_2500TFD:
553                                 vars->line_speed = SPEED_2500;
554                                 break;
555
556                         case LINK_10GTFD:
557                                 vars->line_speed = SPEED_10000;
558                                 break;
559
560                         case LINK_12GTFD:
561                                 vars->line_speed = SPEED_12000;
562                                 break;
563
564                         case LINK_12_5GTFD:
565                                 vars->line_speed = SPEED_12500;
566                                 break;
567
568                         case LINK_13GTFD:
569                                 vars->line_speed = SPEED_13000;
570                                 break;
571
572                         case LINK_15GTFD:
573                                 vars->line_speed = SPEED_15000;
574                                 break;
575
576                         case LINK_16GTFD:
577                                 vars->line_speed = SPEED_16000;
578                                 break;
579
580                         default:
581                                 break;
582                 }
583
584                 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
585                         vars->flow_ctrl |= FLOW_CTRL_TX;
586                 else
587                         vars->flow_ctrl &= ~FLOW_CTRL_TX;
588
589                 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
590                         vars->flow_ctrl |= FLOW_CTRL_RX;
591                 else
592                         vars->flow_ctrl &= ~FLOW_CTRL_RX;
593
594                 if (vars->phy_flags & PHY_XGXS_FLAG) {
595                         if (vars->line_speed &&
596                             ((vars->line_speed == SPEED_10) ||
597                              (vars->line_speed == SPEED_100))) {
598                                 vars->phy_flags |= PHY_SGMII_FLAG;
599                         } else {
600                                 vars->phy_flags &= ~PHY_SGMII_FLAG;
601                         }
602                 }
603
604                 /* anything 10 and over uses the bmac */
605                 link_10g = ((vars->line_speed == SPEED_10000) ||
606                             (vars->line_speed == SPEED_12000) ||
607                             (vars->line_speed == SPEED_12500) ||
608                             (vars->line_speed == SPEED_13000) ||
609                             (vars->line_speed == SPEED_15000) ||
610                             (vars->line_speed == SPEED_16000));
611                 if (link_10g)
612                         vars->mac_type = MAC_TYPE_BMAC;
613                 else
614                         vars->mac_type = MAC_TYPE_EMAC;
615
616         } else { /* link down */
617                 DP(NETIF_MSG_LINK, "phy link down\n");
618
619                 vars->phy_link_up = 0;
620
621                 vars->line_speed = 0;
622                 vars->duplex = DUPLEX_FULL;
623                 vars->flow_ctrl = FLOW_CTRL_NONE;
624
625                 /* indicate no mac active */
626                 vars->mac_type = MAC_TYPE_NONE;
627         }
628
629         DP(NETIF_MSG_LINK, "link_status 0x%x  phy_link_up %x\n",
630                  vars->link_status, vars->phy_link_up);
631         DP(NETIF_MSG_LINK, "line_speed %x  duplex %x  flow_ctrl 0x%x\n",
632                  vars->line_speed, vars->duplex, vars->flow_ctrl);
633 }
634
635 static void bnx2x_update_mng(struct link_params *params, u32 link_status)
636 {
637         struct bnx2x *bp = params->bp;
638         REG_WR(bp, params->shmem_base +
639                    offsetof(struct shmem_region,
640                             port_mb[params->port].link_status),
641                         link_status);
642 }
643
644 static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
645 {
646         u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
647                 NIG_REG_INGRESS_BMAC0_MEM;
648         u32 wb_data[2];
649     u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
650
651         /* Only if the bmac is out of reset */
652         if (REG_RD(bp, MISC_REG_RESET_REG_2) &
653                         (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
654             nig_bmac_enable) {
655
656                 /* Clear Rx Enable bit in BMAC_CONTROL register */
657                 REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
658                             wb_data, 2);
659                 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
660                 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
661                             wb_data, 2);
662
663                 msleep(1);
664         }
665 }
666
667 static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
668                          u32 line_speed)
669 {
670         struct bnx2x *bp = params->bp;
671         u8 port = params->port;
672         u32 init_crd, crd;
673         u32 count = 1000;
674
675         /* disable port */
676         REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
677
678         /* wait for init credit */
679         init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
680         crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
681         DP(NETIF_MSG_LINK, "init_crd 0x%x  crd 0x%x\n", init_crd, crd);
682
683         while ((init_crd != crd) && count) {
684                 msleep(5);
685
686                 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
687                 count--;
688         }
689         crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
690         if (init_crd != crd) {
691                 DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
692                           init_crd, crd);
693                 return -EINVAL;
694         }
695
696         if (flow_ctrl & FLOW_CTRL_RX ||
697             line_speed == SPEED_10 ||
698             line_speed == SPEED_100 ||
699             line_speed == SPEED_1000 ||
700             line_speed == SPEED_2500) {
701                 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
702                 /* update threshold */
703                 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
704                 /* update init credit */
705                 init_crd = 778;         /* (800-18-4) */
706
707         } else {
708                 u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
709                               ETH_OVREHEAD)/16;
710                 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
711                 /* update threshold */
712                 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
713                 /* update init credit */
714                 switch (line_speed) {
715                 case SPEED_10000:
716                         init_crd = thresh + 553 - 22;
717                         break;
718
719                 case SPEED_12000:
720                         init_crd = thresh + 664 - 22;
721                         break;
722
723                 case SPEED_13000:
724                         init_crd = thresh + 742 - 22;
725                         break;
726
727                 case SPEED_16000:
728                         init_crd = thresh + 778 - 22;
729                         break;
730                 default:
731                         DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
732                                   line_speed);
733                         return -EINVAL;
734                         break;
735                 }
736         }
737         REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
738         DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
739                  line_speed, init_crd);
740
741         /* probe the credit changes */
742         REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
743         msleep(5);
744         REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
745
746         /* enable port */
747         REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
748         return 0;
749 }
750
751 static u32 bnx2x_get_emac_base(u32 ext_phy_type, u8 port)
752 {
753         u32 emac_base;
754         switch (ext_phy_type) {
755         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
756                 emac_base = GRCBASE_EMAC0;
757                 break;
758         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
759                 emac_base = (port) ? GRCBASE_EMAC0: GRCBASE_EMAC1;
760                 break;
761         default:
762                 emac_base = (port) ? GRCBASE_EMAC1: GRCBASE_EMAC0;
763                 break;
764         }
765         return emac_base;
766
767 }
768
769 u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
770                   u8 phy_addr, u8 devad, u16 reg, u16 val)
771 {
772         u32 tmp, saved_mode;
773         u8 i, rc = 0;
774         u32 mdio_ctrl = bnx2x_get_emac_base(ext_phy_type, port);
775
776         /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
777          * (a value of 49==0x31) and make sure that the AUTO poll is off
778          */
779         saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
780         tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
781                              EMAC_MDIO_MODE_CLOCK_CNT);
782         tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
783                 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
784         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
785         REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
786         udelay(40);
787
788         /* address */
789
790         tmp = ((phy_addr << 21) | (devad << 16) | reg |
791                EMAC_MDIO_COMM_COMMAND_ADDRESS |
792                EMAC_MDIO_COMM_START_BUSY);
793         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
794
795         for (i = 0; i < 50; i++) {
796                 udelay(10);
797
798                 tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
799                 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
800                         udelay(5);
801                         break;
802                 }
803         }
804         if (tmp & EMAC_MDIO_COMM_START_BUSY) {
805                 DP(NETIF_MSG_LINK, "write phy register failed\n");
806                 rc = -EFAULT;
807         } else {
808                 /* data */
809                 tmp = ((phy_addr << 21) | (devad << 16) | val |
810                        EMAC_MDIO_COMM_COMMAND_WRITE_45 |
811                        EMAC_MDIO_COMM_START_BUSY);
812                 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
813
814                 for (i = 0; i < 50; i++) {
815                         udelay(10);
816
817                         tmp = REG_RD(bp, mdio_ctrl +
818                                          EMAC_REG_EMAC_MDIO_COMM);
819                         if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
820                                 udelay(5);
821                                 break;
822                         }
823                 }
824                 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
825                         DP(NETIF_MSG_LINK, "write phy register failed\n");
826                         rc = -EFAULT;
827                 }
828         }
829
830         /* Restore the saved mode */
831         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
832
833         return rc;
834 }
835
836 u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
837                  u8 phy_addr, u8 devad, u16 reg, u16 *ret_val)
838 {
839         u32 val, saved_mode;
840         u16 i;
841         u8 rc = 0;
842
843         u32 mdio_ctrl = bnx2x_get_emac_base(ext_phy_type, port);
844         /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
845          * (a value of 49==0x31) and make sure that the AUTO poll is off
846          */
847         saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
848         val = saved_mode & ((EMAC_MDIO_MODE_AUTO_POLL |
849                              EMAC_MDIO_MODE_CLOCK_CNT));
850         val |= (EMAC_MDIO_MODE_CLAUSE_45 |
851                 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
852         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
853         REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
854         udelay(40);
855
856         /* address */
857         val = ((phy_addr << 21) | (devad << 16) | reg |
858                EMAC_MDIO_COMM_COMMAND_ADDRESS |
859                EMAC_MDIO_COMM_START_BUSY);
860         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
861
862         for (i = 0; i < 50; i++) {
863                 udelay(10);
864
865                 val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
866                 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
867                         udelay(5);
868                         break;
869                 }
870         }
871         if (val & EMAC_MDIO_COMM_START_BUSY) {
872                 DP(NETIF_MSG_LINK, "read phy register failed\n");
873
874                 *ret_val = 0;
875                 rc = -EFAULT;
876
877         } else {
878                 /* data */
879                 val = ((phy_addr << 21) | (devad << 16) |
880                        EMAC_MDIO_COMM_COMMAND_READ_45 |
881                        EMAC_MDIO_COMM_START_BUSY);
882                 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
883
884                 for (i = 0; i < 50; i++) {
885                         udelay(10);
886
887                         val = REG_RD(bp, mdio_ctrl +
888                                           EMAC_REG_EMAC_MDIO_COMM);
889                         if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
890                                 *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
891                                 break;
892                         }
893                 }
894                 if (val & EMAC_MDIO_COMM_START_BUSY) {
895                         DP(NETIF_MSG_LINK, "read phy register failed\n");
896
897                         *ret_val = 0;
898                         rc = -EFAULT;
899                 }
900         }
901
902         /* Restore the saved mode */
903         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
904
905         return rc;
906 }
907
908 static void bnx2x_set_aer_mmd(struct link_params *params,
909                             struct link_vars   *vars)
910 {
911         struct bnx2x *bp = params->bp;
912         u32 ser_lane;
913         u16 offset;
914
915         ser_lane = ((params->lane_config &
916                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
917                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
918
919         offset = (vars->phy_flags & PHY_XGXS_FLAG) ?
920                 (params->phy_addr + ser_lane) : 0;
921
922         CL45_WR_OVER_CL22(bp, params->port,
923                               params->phy_addr,
924                               MDIO_REG_BANK_AER_BLOCK,
925                               MDIO_AER_BLOCK_AER_REG, 0x3800 + offset);
926 }
927
928 static void bnx2x_set_master_ln(struct link_params *params)
929 {
930         struct bnx2x *bp = params->bp;
931         u16 new_master_ln, ser_lane;
932         ser_lane =  ((params->lane_config &
933                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
934                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
935
936         /* set the master_ln for AN */
937         CL45_RD_OVER_CL22(bp, params->port,
938                               params->phy_addr,
939                               MDIO_REG_BANK_XGXS_BLOCK2,
940                               MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
941                               &new_master_ln);
942
943         CL45_WR_OVER_CL22(bp, params->port,
944                               params->phy_addr,
945                               MDIO_REG_BANK_XGXS_BLOCK2 ,
946                               MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
947                               (new_master_ln | ser_lane));
948 }
949
950 static u8 bnx2x_reset_unicore(struct link_params *params)
951 {
952         struct bnx2x *bp = params->bp;
953         u16 mii_control;
954         u16 i;
955
956         CL45_RD_OVER_CL22(bp, params->port,
957                               params->phy_addr,
958                               MDIO_REG_BANK_COMBO_IEEE0,
959                               MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
960
961         /* reset the unicore */
962         CL45_WR_OVER_CL22(bp, params->port,
963                               params->phy_addr,
964                               MDIO_REG_BANK_COMBO_IEEE0,
965                               MDIO_COMBO_IEEE0_MII_CONTROL,
966                               (mii_control |
967                                MDIO_COMBO_IEEO_MII_CONTROL_RESET));
968
969         /* wait for the reset to self clear */
970         for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
971                 udelay(5);
972
973                 /* the reset erased the previous bank value */
974                 CL45_RD_OVER_CL22(bp, params->port,
975                                       params->phy_addr,
976                               MDIO_REG_BANK_COMBO_IEEE0,
977                               MDIO_COMBO_IEEE0_MII_CONTROL,
978                               &mii_control);
979
980                 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
981                         udelay(5);
982                         return 0;
983                 }
984         }
985
986         DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
987         return -EINVAL;
988
989 }
990
991 static void bnx2x_set_swap_lanes(struct link_params *params)
992 {
993         struct bnx2x *bp = params->bp;
994         /* Each two bits represents a lane number:
995            No swap is 0123 => 0x1b no need to enable the swap */
996         u16 ser_lane, rx_lane_swap, tx_lane_swap;
997
998         ser_lane = ((params->lane_config &
999                          PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1000                         PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1001         rx_lane_swap = ((params->lane_config &
1002                              PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
1003                             PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
1004         tx_lane_swap = ((params->lane_config &
1005                              PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
1006                             PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
1007
1008         if (rx_lane_swap != 0x1b) {
1009                 CL45_WR_OVER_CL22(bp, params->port,
1010                                       params->phy_addr,
1011                                     MDIO_REG_BANK_XGXS_BLOCK2,
1012                                     MDIO_XGXS_BLOCK2_RX_LN_SWAP,
1013                                     (rx_lane_swap |
1014                                     MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
1015                                     MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
1016         } else {
1017                 CL45_WR_OVER_CL22(bp, params->port,
1018                                       params->phy_addr,
1019                                       MDIO_REG_BANK_XGXS_BLOCK2,
1020                                       MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
1021         }
1022
1023         if (tx_lane_swap != 0x1b) {
1024                 CL45_WR_OVER_CL22(bp, params->port,
1025                                       params->phy_addr,
1026                                       MDIO_REG_BANK_XGXS_BLOCK2,
1027                                       MDIO_XGXS_BLOCK2_TX_LN_SWAP,
1028                                       (tx_lane_swap |
1029                                        MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
1030         } else {
1031                 CL45_WR_OVER_CL22(bp, params->port,
1032                                       params->phy_addr,
1033                                       MDIO_REG_BANK_XGXS_BLOCK2,
1034                                       MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
1035         }
1036 }
1037
1038 static void bnx2x_set_parallel_detection(struct link_params *params,
1039                                        u8                phy_flags)
1040 {
1041         struct bnx2x *bp = params->bp;
1042         u16 control2;
1043
1044         CL45_RD_OVER_CL22(bp, params->port,
1045                               params->phy_addr,
1046                               MDIO_REG_BANK_SERDES_DIGITAL,
1047                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1048                               &control2);
1049
1050
1051         control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
1052
1053
1054         CL45_WR_OVER_CL22(bp, params->port,
1055                               params->phy_addr,
1056                               MDIO_REG_BANK_SERDES_DIGITAL,
1057                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1058                               control2);
1059
1060         if (phy_flags & PHY_XGXS_FLAG) {
1061                 DP(NETIF_MSG_LINK, "XGXS\n");
1062
1063                 CL45_WR_OVER_CL22(bp, params->port,
1064                                       params->phy_addr,
1065                                 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1066                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
1067                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
1068
1069                 CL45_RD_OVER_CL22(bp, params->port,
1070                                       params->phy_addr,
1071                                 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1072                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1073                                 &control2);
1074
1075
1076                 control2 |=
1077                     MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
1078
1079                 CL45_WR_OVER_CL22(bp, params->port,
1080                                       params->phy_addr,
1081                                 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1082                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1083                                 control2);
1084
1085                 /* Disable parallel detection of HiG */
1086                 CL45_WR_OVER_CL22(bp, params->port,
1087                                       params->phy_addr,
1088                                 MDIO_REG_BANK_XGXS_BLOCK2,
1089                                 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
1090                                 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
1091                                 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
1092         }
1093 }
1094
1095 static void bnx2x_set_autoneg(struct link_params *params,
1096                             struct link_vars   *vars)
1097 {
1098         struct bnx2x *bp = params->bp;
1099         u16 reg_val;
1100
1101         /* CL37 Autoneg */
1102
1103         CL45_RD_OVER_CL22(bp, params->port,
1104                               params->phy_addr,
1105                               MDIO_REG_BANK_COMBO_IEEE0,
1106                               MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
1107
1108         /* CL37 Autoneg Enabled */
1109         if (vars->line_speed == SPEED_AUTO_NEG)
1110                 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
1111         else /* CL37 Autoneg Disabled */
1112                 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1113                              MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
1114
1115         CL45_WR_OVER_CL22(bp, params->port,
1116                               params->phy_addr,
1117                               MDIO_REG_BANK_COMBO_IEEE0,
1118                               MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1119
1120         /* Enable/Disable Autodetection */
1121
1122         CL45_RD_OVER_CL22(bp, params->port,
1123                               params->phy_addr,
1124                               MDIO_REG_BANK_SERDES_DIGITAL,
1125                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
1126         reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN;
1127         if (vars->line_speed == SPEED_AUTO_NEG)
1128                 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1129         else
1130                 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1131
1132         CL45_WR_OVER_CL22(bp, params->port,
1133                               params->phy_addr,
1134                               MDIO_REG_BANK_SERDES_DIGITAL,
1135                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
1136
1137         /* Enable TetonII and BAM autoneg */
1138         CL45_RD_OVER_CL22(bp, params->port,
1139                               params->phy_addr,
1140                               MDIO_REG_BANK_BAM_NEXT_PAGE,
1141                               MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1142                           &reg_val);
1143         if (vars->line_speed == SPEED_AUTO_NEG) {
1144                 /* Enable BAM aneg Mode and TetonII aneg Mode */
1145                 reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1146                             MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1147         } else {
1148                 /* TetonII and BAM Autoneg Disabled */
1149                 reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1150                              MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1151         }
1152         CL45_WR_OVER_CL22(bp, params->port,
1153                               params->phy_addr,
1154                               MDIO_REG_BANK_BAM_NEXT_PAGE,
1155                               MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1156                               reg_val);
1157
1158         /* Enable Clause 73 Aneg */
1159         if ((vars->line_speed == SPEED_AUTO_NEG) &&
1160             (SUPPORT_CL73)) {
1161                 /* Enable BAM Station Manager */
1162
1163                 CL45_WR_OVER_CL22(bp, params->port,
1164                                       params->phy_addr,
1165                                       MDIO_REG_BANK_CL73_USERB0,
1166                                       MDIO_CL73_USERB0_CL73_BAM_CTRL1,
1167                                    (MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
1168                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
1169                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN));
1170
1171                 /* Merge CL73 and CL37 aneg resolution */
1172                 CL45_RD_OVER_CL22(bp, params->port,
1173                                       params->phy_addr,
1174                                       MDIO_REG_BANK_CL73_USERB0,
1175                                       MDIO_CL73_USERB0_CL73_BAM_CTRL3,
1176                                       &reg_val);
1177
1178                 CL45_WR_OVER_CL22(bp, params->port,
1179                                       params->phy_addr,
1180                         MDIO_REG_BANK_CL73_USERB0,
1181                         MDIO_CL73_USERB0_CL73_BAM_CTRL3,
1182                         (reg_val |
1183                         MDIO_CL73_USERB0_CL73_BAM_CTRL3_USE_CL73_HCD_MR));
1184
1185                 /* Set the CL73 AN speed */
1186
1187                 CL45_RD_OVER_CL22(bp, params->port,
1188                                       params->phy_addr,
1189                                       MDIO_REG_BANK_CL73_IEEEB1,
1190                                       MDIO_CL73_IEEEB1_AN_ADV2, &reg_val);
1191                 /* In the SerDes we support only the 1G.
1192                    In the XGXS we support the 10G KX4
1193                    but we currently do not support the KR */
1194                 if (vars->phy_flags & PHY_XGXS_FLAG) {
1195                         DP(NETIF_MSG_LINK, "XGXS\n");
1196                         /* 10G KX4 */
1197                         reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
1198                 } else {
1199                         DP(NETIF_MSG_LINK, "SerDes\n");
1200                         /* 1000M KX */
1201                         reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
1202                 }
1203                 CL45_WR_OVER_CL22(bp, params->port,
1204                                       params->phy_addr,
1205                                       MDIO_REG_BANK_CL73_IEEEB1,
1206                                       MDIO_CL73_IEEEB1_AN_ADV2, reg_val);
1207
1208                 /* CL73 Autoneg Enabled */
1209                 reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
1210         } else {
1211                 /* CL73 Autoneg Disabled */
1212                 reg_val = 0;
1213         }
1214         CL45_WR_OVER_CL22(bp, params->port,
1215                               params->phy_addr,
1216                               MDIO_REG_BANK_CL73_IEEEB0,
1217                               MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
1218 }
1219
1220 /* program SerDes, forced speed */
1221 static void bnx2x_program_serdes(struct link_params *params,
1222                                struct link_vars *vars)
1223 {
1224         struct bnx2x *bp = params->bp;
1225         u16 reg_val;
1226
1227         /* program duplex, disable autoneg */
1228
1229         CL45_RD_OVER_CL22(bp, params->port,
1230                               params->phy_addr,
1231                               MDIO_REG_BANK_COMBO_IEEE0,
1232                               MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
1233         reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
1234                      MDIO_COMBO_IEEO_MII_CONTROL_AN_EN);
1235         if (params->req_duplex == DUPLEX_FULL)
1236                 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1237         CL45_WR_OVER_CL22(bp, params->port,
1238                               params->phy_addr,
1239                               MDIO_REG_BANK_COMBO_IEEE0,
1240                               MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1241
1242         /* program speed
1243            - needed only if the speed is greater than 1G (2.5G or 10G) */
1244         CL45_RD_OVER_CL22(bp, params->port,
1245                                       params->phy_addr,
1246                                       MDIO_REG_BANK_SERDES_DIGITAL,
1247                                       MDIO_SERDES_DIGITAL_MISC1, &reg_val);
1248         /* clearing the speed value before setting the right speed */
1249         DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
1250
1251         reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
1252                      MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1253
1254         if (!((vars->line_speed == SPEED_1000) ||
1255               (vars->line_speed == SPEED_100) ||
1256               (vars->line_speed == SPEED_10))) {
1257
1258                 reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
1259                             MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1260                 if (vars->line_speed == SPEED_10000)
1261                         reg_val |=
1262                                 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
1263                 if (vars->line_speed == SPEED_13000)
1264                         reg_val |=
1265                                 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G;
1266         }
1267
1268         CL45_WR_OVER_CL22(bp, params->port,
1269                                       params->phy_addr,
1270                                       MDIO_REG_BANK_SERDES_DIGITAL,
1271                                       MDIO_SERDES_DIGITAL_MISC1, reg_val);
1272
1273 }
1274
1275 static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params)
1276 {
1277         struct bnx2x *bp = params->bp;
1278         u16 val = 0;
1279
1280         /* configure the 48 bits for BAM AN */
1281
1282         /* set extended capabilities */
1283         if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
1284                 val |= MDIO_OVER_1G_UP1_2_5G;
1285         if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
1286                 val |= MDIO_OVER_1G_UP1_10G;
1287         CL45_WR_OVER_CL22(bp, params->port,
1288                               params->phy_addr,
1289                               MDIO_REG_BANK_OVER_1G,
1290                               MDIO_OVER_1G_UP1, val);
1291
1292         CL45_WR_OVER_CL22(bp, params->port,
1293                               params->phy_addr,
1294                               MDIO_REG_BANK_OVER_1G,
1295                               MDIO_OVER_1G_UP3, 0);
1296 }
1297
1298 static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u32 *ieee_fc)
1299 {
1300         *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
1301         /* resolve pause mode and advertisement
1302          * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
1303
1304         switch (params->req_flow_ctrl) {
1305         case FLOW_CTRL_AUTO:
1306                 if (params->req_fc_auto_adv == FLOW_CTRL_BOTH) {
1307                         *ieee_fc |=
1308                              MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1309                 } else {
1310                         *ieee_fc |=
1311                        MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1312                 }
1313                 break;
1314         case FLOW_CTRL_TX:
1315                 *ieee_fc |=
1316                        MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1317                 break;
1318
1319         case FLOW_CTRL_RX:
1320         case FLOW_CTRL_BOTH:
1321                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1322                 break;
1323
1324         case FLOW_CTRL_NONE:
1325         default:
1326                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
1327                 break;
1328         }
1329 }
1330
1331 static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params,
1332                                            u32 ieee_fc)
1333 {
1334         struct bnx2x *bp = params->bp;
1335         /* for AN, we are always publishing full duplex */
1336
1337         CL45_WR_OVER_CL22(bp, params->port,
1338                               params->phy_addr,
1339                               MDIO_REG_BANK_COMBO_IEEE0,
1340                               MDIO_COMBO_IEEE0_AUTO_NEG_ADV, (u16)ieee_fc);
1341 }
1342
1343 static void bnx2x_restart_autoneg(struct link_params *params)
1344 {
1345         struct bnx2x *bp = params->bp;
1346         DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
1347         if (SUPPORT_CL73) {
1348                 /* enable and restart clause 73 aneg */
1349                 u16 an_ctrl;
1350
1351                 CL45_RD_OVER_CL22(bp, params->port,
1352                                       params->phy_addr,
1353                                       MDIO_REG_BANK_CL73_IEEEB0,
1354                                       MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1355                                   &an_ctrl);
1356                 CL45_WR_OVER_CL22(bp, params->port,
1357                                       params->phy_addr,
1358                                 MDIO_REG_BANK_CL73_IEEEB0,
1359                                 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1360                                 (an_ctrl |
1361                                 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
1362                                 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
1363
1364         } else {
1365                 /* Enable and restart BAM/CL37 aneg */
1366                 u16 mii_control;
1367
1368                 CL45_RD_OVER_CL22(bp, params->port,
1369                                       params->phy_addr,
1370                                       MDIO_REG_BANK_COMBO_IEEE0,
1371                                       MDIO_COMBO_IEEE0_MII_CONTROL,
1372                                       &mii_control);
1373                 DP(NETIF_MSG_LINK,
1374                          "bnx2x_restart_autoneg mii_control before = 0x%x\n",
1375                          mii_control);
1376                 CL45_WR_OVER_CL22(bp, params->port,
1377                                       params->phy_addr,
1378                                       MDIO_REG_BANK_COMBO_IEEE0,
1379                                       MDIO_COMBO_IEEE0_MII_CONTROL,
1380                                       (mii_control |
1381                                 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1382                                 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
1383         }
1384 }
1385
1386 static void bnx2x_initialize_sgmii_process(struct link_params *params,
1387                                          struct link_vars *vars)
1388 {
1389         struct bnx2x *bp = params->bp;
1390         u16 control1;
1391
1392         /* in SGMII mode, the unicore is always slave */
1393
1394         CL45_RD_OVER_CL22(bp, params->port,
1395                               params->phy_addr,
1396                               MDIO_REG_BANK_SERDES_DIGITAL,
1397                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1398                       &control1);
1399         control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
1400         /* set sgmii mode (and not fiber) */
1401         control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
1402                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
1403                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
1404         CL45_WR_OVER_CL22(bp, params->port,
1405                               params->phy_addr,
1406                               MDIO_REG_BANK_SERDES_DIGITAL,
1407                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1408                               control1);
1409
1410         /* if forced speed */
1411         if (!(vars->line_speed == SPEED_AUTO_NEG)) {
1412                 /* set speed, disable autoneg */
1413                 u16 mii_control;
1414
1415                 CL45_RD_OVER_CL22(bp, params->port,
1416                                       params->phy_addr,
1417                                       MDIO_REG_BANK_COMBO_IEEE0,
1418                                       MDIO_COMBO_IEEE0_MII_CONTROL,
1419                                       &mii_control);
1420                 mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1421                                  MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
1422                                  MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
1423
1424                 switch (vars->line_speed) {
1425                 case SPEED_100:
1426                         mii_control |=
1427                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
1428                         break;
1429                 case SPEED_1000:
1430                         mii_control |=
1431                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
1432                         break;
1433                 case SPEED_10:
1434                         /* there is nothing to set for 10M */
1435                         break;
1436                 default:
1437                         /* invalid speed for SGMII */
1438                         DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
1439                                   vars->line_speed);
1440                         break;
1441                 }
1442
1443                 /* setting the full duplex */
1444                 if (params->req_duplex == DUPLEX_FULL)
1445                         mii_control |=
1446                                 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1447                 CL45_WR_OVER_CL22(bp, params->port,
1448                                       params->phy_addr,
1449                                       MDIO_REG_BANK_COMBO_IEEE0,
1450                                       MDIO_COMBO_IEEE0_MII_CONTROL,
1451                                       mii_control);
1452
1453         } else { /* AN mode */
1454                 /* enable and restart AN */
1455                 bnx2x_restart_autoneg(params);
1456         }
1457 }
1458
1459
1460 /*
1461  * link management
1462  */
1463
1464 static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
1465 {                                               /*  LD      LP   */
1466         switch (pause_result) {                 /* ASYM P ASYM P */
1467         case 0xb:                               /*   1  0   1  1 */
1468                 vars->flow_ctrl = FLOW_CTRL_TX;
1469                 break;
1470
1471         case 0xe:                               /*   1  1   1  0 */
1472                 vars->flow_ctrl = FLOW_CTRL_RX;
1473                 break;
1474
1475         case 0x5:                               /*   0  1   0  1 */
1476         case 0x7:                               /*   0  1   1  1 */
1477         case 0xd:                               /*   1  1   0  1 */
1478         case 0xf:                               /*   1  1   1  1 */
1479                 vars->flow_ctrl = FLOW_CTRL_BOTH;
1480                 break;
1481
1482         default:
1483                 break;
1484         }
1485 }
1486
1487 static u8 bnx2x_ext_phy_resove_fc(struct link_params *params,
1488                                   struct link_vars *vars)
1489 {
1490         struct bnx2x *bp = params->bp;
1491         u8 ext_phy_addr;
1492         u16 ld_pause;   /* local */
1493         u16 lp_pause;   /* link partner */
1494         u16 an_complete; /* AN complete */
1495         u16 pause_result;
1496         u8 ret = 0;
1497         u32 ext_phy_type;
1498         u8 port = params->port;
1499         ext_phy_addr = ((params->ext_phy_config &
1500                          PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1501                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1502
1503         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1504         /* read twice */
1505
1506         bnx2x_cl45_read(bp, port,
1507                       ext_phy_type,
1508                       ext_phy_addr,
1509                       MDIO_AN_DEVAD,
1510                       MDIO_AN_REG_STATUS, &an_complete);
1511         bnx2x_cl45_read(bp, port,
1512                       ext_phy_type,
1513                       ext_phy_addr,
1514                       MDIO_AN_DEVAD,
1515                       MDIO_AN_REG_STATUS, &an_complete);
1516
1517         if (an_complete & MDIO_AN_REG_STATUS_AN_COMPLETE) {
1518                 ret = 1;
1519                 bnx2x_cl45_read(bp, port,
1520                               ext_phy_type,
1521                               ext_phy_addr,
1522                               MDIO_AN_DEVAD,
1523                               MDIO_AN_REG_ADV_PAUSE, &ld_pause);
1524                 bnx2x_cl45_read(bp, port,
1525                               ext_phy_type,
1526                               ext_phy_addr,
1527                               MDIO_AN_DEVAD,
1528                               MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
1529                 pause_result = (ld_pause &
1530                                 MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
1531                 pause_result |= (lp_pause &
1532                                  MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
1533                 DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x \n",
1534                    pause_result);
1535                 bnx2x_pause_resolve(vars, pause_result);
1536                 if (vars->flow_ctrl == FLOW_CTRL_NONE &&
1537                      ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
1538                         bnx2x_cl45_read(bp, port,
1539                                       ext_phy_type,
1540                                       ext_phy_addr,
1541                                       MDIO_AN_DEVAD,
1542                                       MDIO_AN_REG_CL37_FC_LD, &ld_pause);
1543
1544                         bnx2x_cl45_read(bp, port,
1545                                       ext_phy_type,
1546                                       ext_phy_addr,
1547                                       MDIO_AN_DEVAD,
1548                                       MDIO_AN_REG_CL37_FC_LP, &lp_pause);
1549                         pause_result = (ld_pause &
1550                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
1551                         pause_result |= (lp_pause &
1552                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
1553
1554                         bnx2x_pause_resolve(vars, pause_result);
1555                         DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x \n",
1556                                  pause_result);
1557                 }
1558         }
1559         return ret;
1560 }
1561
1562
1563 static void bnx2x_flow_ctrl_resolve(struct link_params *params,
1564                                   struct link_vars *vars,
1565                                   u32 gp_status)
1566 {
1567         struct bnx2x *bp = params->bp;
1568         u16 ld_pause;   /* local driver */
1569         u16 lp_pause;   /* link partner */
1570         u16 pause_result;
1571
1572         vars->flow_ctrl = FLOW_CTRL_NONE;
1573
1574         /* resolve from gp_status in case of AN complete and not sgmii */
1575         if ((params->req_flow_ctrl == FLOW_CTRL_AUTO) &&
1576             (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
1577             (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
1578             (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1579              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) {
1580                 CL45_RD_OVER_CL22(bp, params->port,
1581                                       params->phy_addr,
1582                                       MDIO_REG_BANK_COMBO_IEEE0,
1583                                       MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
1584                                       &ld_pause);
1585                 CL45_RD_OVER_CL22(bp, params->port,
1586                                       params->phy_addr,
1587                         MDIO_REG_BANK_COMBO_IEEE0,
1588                         MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
1589                         &lp_pause);
1590                 pause_result = (ld_pause &
1591                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
1592                 pause_result |= (lp_pause &
1593                                  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
1594                 DP(NETIF_MSG_LINK, "pause_result 0x%x\n", pause_result);
1595                 bnx2x_pause_resolve(vars, pause_result);
1596         } else if ((params->req_flow_ctrl == FLOW_CTRL_AUTO) &&
1597                    (bnx2x_ext_phy_resove_fc(params, vars))) {
1598                 return;
1599         } else {
1600                 if (params->req_flow_ctrl == FLOW_CTRL_AUTO)
1601                         vars->flow_ctrl = params->req_fc_auto_adv;
1602                 else
1603                         vars->flow_ctrl = params->req_flow_ctrl;
1604         }
1605         DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
1606 }
1607
1608
1609 static u8 bnx2x_link_settings_status(struct link_params *params,
1610                                       struct link_vars *vars,
1611                                       u32 gp_status)
1612 {
1613         struct bnx2x *bp = params->bp;
1614         u8 rc = 0;
1615         vars->link_status = 0;
1616
1617         if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
1618                 DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n",
1619                          gp_status);
1620
1621                 vars->phy_link_up = 1;
1622                 vars->link_status |= LINK_STATUS_LINK_UP;
1623
1624                 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
1625                         vars->duplex = DUPLEX_FULL;
1626                 else
1627                         vars->duplex = DUPLEX_HALF;
1628
1629                 bnx2x_flow_ctrl_resolve(params, vars, gp_status);
1630
1631                 switch (gp_status & GP_STATUS_SPEED_MASK) {
1632                 case GP_STATUS_10M:
1633                         vars->line_speed = SPEED_10;
1634                         if (vars->duplex == DUPLEX_FULL)
1635                                 vars->link_status |= LINK_10TFD;
1636                         else
1637                                 vars->link_status |= LINK_10THD;
1638                         break;
1639
1640                 case GP_STATUS_100M:
1641                         vars->line_speed = SPEED_100;
1642                         if (vars->duplex == DUPLEX_FULL)
1643                                 vars->link_status |= LINK_100TXFD;
1644                         else
1645                                 vars->link_status |= LINK_100TXHD;
1646                         break;
1647
1648                 case GP_STATUS_1G:
1649                 case GP_STATUS_1G_KX:
1650                         vars->line_speed = SPEED_1000;
1651                         if (vars->duplex == DUPLEX_FULL)
1652                                 vars->link_status |= LINK_1000TFD;
1653                         else
1654                                 vars->link_status |= LINK_1000THD;
1655                         break;
1656
1657                 case GP_STATUS_2_5G:
1658                         vars->line_speed = SPEED_2500;
1659                         if (vars->duplex == DUPLEX_FULL)
1660                                 vars->link_status |= LINK_2500TFD;
1661                         else
1662                                 vars->link_status |= LINK_2500THD;
1663                         break;
1664
1665                 case GP_STATUS_5G:
1666                 case GP_STATUS_6G:
1667                         DP(NETIF_MSG_LINK,
1668                                  "link speed unsupported  gp_status 0x%x\n",
1669                                   gp_status);
1670                         return -EINVAL;
1671                         break;
1672                 case GP_STATUS_10G_KX4:
1673                 case GP_STATUS_10G_HIG:
1674                 case GP_STATUS_10G_CX4:
1675                         vars->line_speed = SPEED_10000;
1676                         vars->link_status |= LINK_10GTFD;
1677                         break;
1678
1679                 case GP_STATUS_12G_HIG:
1680                         vars->line_speed = SPEED_12000;
1681                         vars->link_status |= LINK_12GTFD;
1682                         break;
1683
1684                 case GP_STATUS_12_5G:
1685                         vars->line_speed = SPEED_12500;
1686                         vars->link_status |= LINK_12_5GTFD;
1687                         break;
1688
1689                 case GP_STATUS_13G:
1690                         vars->line_speed = SPEED_13000;
1691                         vars->link_status |= LINK_13GTFD;
1692                         break;
1693
1694                 case GP_STATUS_15G:
1695                         vars->line_speed = SPEED_15000;
1696                         vars->link_status |= LINK_15GTFD;
1697                         break;
1698
1699                 case GP_STATUS_16G:
1700                         vars->line_speed = SPEED_16000;
1701                         vars->link_status |= LINK_16GTFD;
1702                         break;
1703
1704                 default:
1705                         DP(NETIF_MSG_LINK,
1706                                   "link speed unsupported gp_status 0x%x\n",
1707                                   gp_status);
1708                 return -EINVAL;
1709                         break;
1710                 }
1711
1712                 vars->link_status |= LINK_STATUS_SERDES_LINK;
1713
1714                 if ((params->req_line_speed == SPEED_AUTO_NEG) &&
1715                     ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1716                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
1717                     (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1718                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705))) {
1719                         vars->autoneg = AUTO_NEG_ENABLED;
1720
1721                         if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
1722                                 vars->autoneg |= AUTO_NEG_COMPLETE;
1723                                 vars->link_status |=
1724                                         LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
1725                         }
1726
1727                         vars->autoneg |= AUTO_NEG_PARALLEL_DETECTION_USED;
1728                         vars->link_status |=
1729                                 LINK_STATUS_PARALLEL_DETECTION_USED;
1730
1731                 }
1732                 if (vars->flow_ctrl & FLOW_CTRL_TX)
1733                         vars->link_status |=
1734                                 LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
1735
1736                 if (vars->flow_ctrl & FLOW_CTRL_RX)
1737                         vars->link_status |=
1738                                 LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
1739
1740         } else { /* link_down */
1741                 DP(NETIF_MSG_LINK, "phy link down\n");
1742
1743                 vars->phy_link_up = 0;
1744
1745                 vars->duplex = DUPLEX_FULL;
1746                 vars->flow_ctrl = FLOW_CTRL_NONE;
1747                 vars->autoneg = AUTO_NEG_DISABLED;
1748                 vars->mac_type = MAC_TYPE_NONE;
1749         }
1750
1751         DP(NETIF_MSG_LINK, "gp_status 0x%x  phy_link_up %x line_speed %x \n",
1752                  gp_status, vars->phy_link_up, vars->line_speed);
1753         DP(NETIF_MSG_LINK, "duplex %x  flow_ctrl 0x%x"
1754                  " autoneg 0x%x\n",
1755                  vars->duplex,
1756                  vars->flow_ctrl, vars->autoneg);
1757         DP(NETIF_MSG_LINK, "link_status 0x%x\n", vars->link_status);
1758
1759         return rc;
1760 }
1761
1762 static void bnx2x_set_sgmii_tx_driver(struct link_params *params)
1763 {
1764         struct bnx2x *bp = params->bp;
1765         u16 lp_up2;
1766         u16 tx_driver;
1767
1768         /* read precomp */
1769
1770         CL45_RD_OVER_CL22(bp, params->port,
1771                               params->phy_addr,
1772                               MDIO_REG_BANK_OVER_1G,
1773                               MDIO_OVER_1G_LP_UP2, &lp_up2);
1774
1775         CL45_RD_OVER_CL22(bp, params->port,
1776                               params->phy_addr,
1777                               MDIO_REG_BANK_TX0,
1778                               MDIO_TX0_TX_DRIVER, &tx_driver);
1779
1780         /* bits [10:7] at lp_up2, positioned at [15:12] */
1781         lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
1782                    MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
1783                   MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
1784
1785         if ((lp_up2 != 0) &&
1786             (lp_up2 != (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK))) {
1787                 /* replace tx_driver bits [15:12] */
1788                 tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
1789                 tx_driver |= lp_up2;
1790                 CL45_WR_OVER_CL22(bp, params->port,
1791                                       params->phy_addr,
1792                                       MDIO_REG_BANK_TX0,
1793                                       MDIO_TX0_TX_DRIVER, tx_driver);
1794         }
1795 }
1796
1797 static u8 bnx2x_emac_program(struct link_params *params,
1798                            u32 line_speed, u32 duplex)
1799 {
1800         struct bnx2x *bp = params->bp;
1801         u8 port = params->port;
1802         u16 mode = 0;
1803
1804         DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
1805         bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
1806                      EMAC_REG_EMAC_MODE,
1807                      (EMAC_MODE_25G_MODE |
1808                      EMAC_MODE_PORT_MII_10M |
1809                      EMAC_MODE_HALF_DUPLEX));
1810         switch (line_speed) {
1811         case SPEED_10:
1812                 mode |= EMAC_MODE_PORT_MII_10M;
1813                 break;
1814
1815         case SPEED_100:
1816                 mode |= EMAC_MODE_PORT_MII;
1817                 break;
1818
1819         case SPEED_1000:
1820                 mode |= EMAC_MODE_PORT_GMII;
1821                 break;
1822
1823         case SPEED_2500:
1824                 mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
1825                 break;
1826
1827         default:
1828                 /* 10G not valid for EMAC */
1829                 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", line_speed);
1830                 return -EINVAL;
1831         }
1832
1833         if (duplex == DUPLEX_HALF)
1834                 mode |= EMAC_MODE_HALF_DUPLEX;
1835         bnx2x_bits_en(bp,
1836                     GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
1837                     mode);
1838
1839         bnx2x_set_led(bp, params->port, LED_MODE_OPER,
1840                     line_speed, params->hw_led_mode, params->chip_id);
1841         return 0;
1842 }
1843
1844 /*****************************************************************************/
1845 /*                           External Phy section                            */
1846 /*****************************************************************************/
1847 static void bnx2x_hw_reset(struct bnx2x *bp, u8 port)
1848 {
1849         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1850                        MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
1851         msleep(1);
1852         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1853                       MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
1854 }
1855
1856 static void bnx2x_ext_phy_reset(struct link_params *params,
1857                               struct link_vars   *vars)
1858 {
1859         struct bnx2x *bp = params->bp;
1860         u32 ext_phy_type;
1861         u8 ext_phy_addr = ((params->ext_phy_config &
1862                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1863                            PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1864         DP(NETIF_MSG_LINK, "Port %x: bnx2x_ext_phy_reset\n", params->port);
1865         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1866         /* The PHY reset is controled by GPIO 1
1867          * Give it 1ms of reset pulse
1868          */
1869         if (vars->phy_flags & PHY_XGXS_FLAG) {
1870
1871                 switch (ext_phy_type) {
1872                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
1873                         DP(NETIF_MSG_LINK, "XGXS Direct\n");
1874                         break;
1875
1876                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
1877                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
1878                         DP(NETIF_MSG_LINK, "XGXS 8705/8706\n");
1879
1880                         /* Restore normal power mode*/
1881                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1882                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1883                                           params->port);
1884
1885                         /* HW reset */
1886                         bnx2x_hw_reset(bp, params->port);
1887
1888                         bnx2x_cl45_write(bp, params->port,
1889                                        ext_phy_type,
1890                                        ext_phy_addr,
1891                                        MDIO_PMA_DEVAD,
1892                                        MDIO_PMA_REG_CTRL, 0xa040);
1893                         break;
1894                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
1895                         /* Unset Low Power Mode and SW reset */
1896                         /* Restore normal power mode*/
1897                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1898                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1899                                           params->port);
1900
1901                         DP(NETIF_MSG_LINK, "XGXS 8072\n");
1902                         bnx2x_cl45_write(bp, params->port,
1903                                        ext_phy_type,
1904                                        ext_phy_addr,
1905                                        MDIO_PMA_DEVAD,
1906                                        MDIO_PMA_REG_CTRL,
1907                                        1<<15);
1908                         break;
1909                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
1910                         {
1911                         u16 emac_base;
1912                         emac_base = (params->port) ? GRCBASE_EMAC0 :
1913                                         GRCBASE_EMAC1;
1914
1915                         /* Restore normal power mode*/
1916                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1917                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1918                                           params->port);
1919
1920                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1921                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1922                                           params->port);
1923
1924                         DP(NETIF_MSG_LINK, "XGXS 8073\n");
1925                         }
1926                         break;
1927
1928                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
1929                         DP(NETIF_MSG_LINK, "XGXS SFX7101\n");
1930
1931                         /* Restore normal power mode*/
1932                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1933                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1934                                           params->port);
1935
1936                         /* HW reset */
1937                         bnx2x_hw_reset(bp, params->port);
1938
1939                         break;
1940
1941                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
1942                         DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n");
1943                         break;
1944
1945                 default:
1946                         DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
1947                            params->ext_phy_config);
1948                         break;
1949                 }
1950
1951         } else { /* SerDes */
1952                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
1953                 switch (ext_phy_type) {
1954                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
1955                         DP(NETIF_MSG_LINK, "SerDes Direct\n");
1956                         break;
1957
1958                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
1959                         DP(NETIF_MSG_LINK, "SerDes 5482\n");
1960                         bnx2x_hw_reset(bp, params->port);
1961                         break;
1962
1963                 default:
1964                         DP(NETIF_MSG_LINK,
1965                                  "BAD SerDes ext_phy_config 0x%x\n",
1966                                  params->ext_phy_config);
1967                         break;
1968                 }
1969         }
1970 }
1971
1972 static void bnx2x_bcm8072_external_rom_boot(struct link_params *params)
1973 {
1974         struct bnx2x *bp = params->bp;
1975         u8 port = params->port;
1976         u8 ext_phy_addr = ((params->ext_phy_config &
1977                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1978                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1979         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1980         u16 fw_ver1, fw_ver2;
1981
1982         /* Need to wait 200ms after reset */
1983         msleep(200);
1984         /* Boot port from external ROM
1985          * Set ser_boot_ctl bit in the MISC_CTRL1 register
1986          */
1987         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
1988                             MDIO_PMA_DEVAD,
1989                             MDIO_PMA_REG_MISC_CTRL1, 0x0001);
1990
1991         /* Reset internal microprocessor */
1992         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
1993                           MDIO_PMA_DEVAD,
1994                           MDIO_PMA_REG_GEN_CTRL,
1995                           MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
1996         /* set micro reset = 0 */
1997         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
1998                             MDIO_PMA_DEVAD,
1999                             MDIO_PMA_REG_GEN_CTRL,
2000                             MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2001         /* Reset internal microprocessor */
2002         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2003                           MDIO_PMA_DEVAD,
2004                           MDIO_PMA_REG_GEN_CTRL,
2005                           MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2006         /* wait for 100ms for code download via SPI port */
2007         msleep(100);
2008
2009         /* Clear ser_boot_ctl bit */
2010         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2011                             MDIO_PMA_DEVAD,
2012                             MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2013         /* Wait 100ms */
2014         msleep(100);
2015
2016         /* Print the PHY FW version */
2017         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2018                             MDIO_PMA_DEVAD,
2019                             MDIO_PMA_REG_ROM_VER1, &fw_ver1);
2020         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2021                             MDIO_PMA_DEVAD,
2022                             MDIO_PMA_REG_ROM_VER2, &fw_ver2);
2023         DP(NETIF_MSG_LINK, "8072 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
2024 }
2025
2026 static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
2027 {
2028         /* This is only required for 8073A1, version 102 only */
2029
2030         struct bnx2x *bp = params->bp;
2031         u8 ext_phy_addr = ((params->ext_phy_config &
2032                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2033                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2034         u16 val;
2035
2036         /* Read 8073 HW revision*/
2037         bnx2x_cl45_read(bp, params->port,
2038                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2039                       ext_phy_addr,
2040                       MDIO_PMA_DEVAD,
2041                       0xc801, &val);
2042
2043         if (val != 1) {
2044                 /* No need to workaround in 8073 A1 */
2045                 return 0;
2046         }
2047
2048         bnx2x_cl45_read(bp, params->port,
2049                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2050                       ext_phy_addr,
2051                       MDIO_PMA_DEVAD,
2052                       MDIO_PMA_REG_ROM_VER2, &val);
2053
2054         /* SNR should be applied only for version 0x102 */
2055         if (val != 0x102)
2056                 return 0;
2057
2058         return 1;
2059 }
2060
2061 static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
2062 {
2063         struct bnx2x *bp = params->bp;
2064         u8 ext_phy_addr = ((params->ext_phy_config &
2065                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2066                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2067         u16 val, cnt, cnt1 ;
2068
2069         bnx2x_cl45_read(bp, params->port,
2070                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2071                       ext_phy_addr,
2072                       MDIO_PMA_DEVAD,
2073                       0xc801, &val);
2074
2075         if (val > 0) {
2076                 /* No need to workaround in 8073 A1 */
2077                 return 0;
2078         }
2079         /* XAUI workaround in 8073 A0: */
2080
2081         /* After loading the boot ROM and restarting Autoneg,
2082         poll Dev1, Reg $C820: */
2083
2084         for (cnt = 0; cnt < 1000; cnt++) {
2085                 bnx2x_cl45_read(bp, params->port,
2086                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2087                               ext_phy_addr,
2088                               MDIO_PMA_DEVAD,
2089                               0xc820, &val);
2090                   /* If bit [14] = 0 or bit [13] = 0, continue on with
2091                    system initialization (XAUI work-around not required,
2092                     as these bits indicate 2.5G or 1G link up). */
2093                 if (!(val & (1<<14)) || !(val & (1<<13))) {
2094                         DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
2095                         return 0;
2096                 } else if (!(val & (1<<15))) {
2097                         DP(NETIF_MSG_LINK, "clc bit 15 went off\n");
2098                          /* If bit 15 is 0, then poll Dev1, Reg $C841 until
2099                           it's MSB (bit 15) goes to 1 (indicating that the
2100                           XAUI workaround has completed),
2101                           then continue on with system initialization.*/
2102                         for (cnt1 = 0; cnt1 < 1000; cnt1++) {
2103                                 bnx2x_cl45_read(bp, params->port,
2104                                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2105                                         ext_phy_addr,
2106                                         MDIO_PMA_DEVAD,
2107                                         0xc841, &val);
2108                                 if (val & (1<<15)) {
2109                                         DP(NETIF_MSG_LINK,
2110                                           "XAUI workaround has completed\n");
2111                                         return 0;
2112                                  }
2113                                  msleep(3);
2114                         }
2115                         break;
2116                 }
2117                 msleep(3);
2118         }
2119         DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
2120         return -EINVAL;
2121
2122 }
2123
2124 static void bnx2x_bcm8073_external_rom_boot(struct link_params *params)
2125 {
2126         struct bnx2x *bp = params->bp;
2127         u8 port = params->port;
2128         u8 ext_phy_addr = ((params->ext_phy_config &
2129                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2130                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2131         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2132         u16 fw_ver1, fw_ver2, val;
2133         /* Need to wait 100ms after reset */
2134         msleep(100);
2135         /* Boot port from external ROM  */
2136         /* EDC grst */
2137         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2138                        MDIO_PMA_DEVAD,
2139                        MDIO_PMA_REG_GEN_CTRL,
2140                        0x0001);
2141
2142         /* ucode reboot and rst */
2143         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2144                        MDIO_PMA_DEVAD,
2145                        MDIO_PMA_REG_GEN_CTRL,
2146                        0x008c);
2147
2148         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2149                        MDIO_PMA_DEVAD,
2150                        MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2151
2152         /* Reset internal microprocessor */
2153         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2154                        MDIO_PMA_DEVAD,
2155                        MDIO_PMA_REG_GEN_CTRL,
2156                        MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2157
2158         /* Release srst bit */
2159         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2160                        MDIO_PMA_DEVAD,
2161                        MDIO_PMA_REG_GEN_CTRL,
2162                        MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2163
2164         /* wait for 100ms for code download via SPI port */
2165         msleep(100);
2166
2167         /* Clear ser_boot_ctl bit */
2168         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2169                        MDIO_PMA_DEVAD,
2170                        MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2171
2172         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2173                        MDIO_PMA_DEVAD,
2174                        MDIO_PMA_REG_ROM_VER1, &fw_ver1);
2175         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2176                        MDIO_PMA_DEVAD,
2177                        MDIO_PMA_REG_ROM_VER2, &fw_ver2);
2178         DP(NETIF_MSG_LINK, "8073 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
2179
2180         /* Only set bit 10 = 1 (Tx power down) */
2181         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2182                        MDIO_PMA_DEVAD,
2183                        MDIO_PMA_REG_TX_POWER_DOWN, &val);
2184
2185         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2186                        MDIO_PMA_DEVAD,
2187                        MDIO_PMA_REG_TX_POWER_DOWN, (val | 1<<10));
2188
2189         msleep(600);
2190         /* Release bit 10 (Release Tx power down) */
2191         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2192                        MDIO_PMA_DEVAD,
2193                        MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
2194
2195 }
2196
2197 static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params)
2198 {
2199         struct bnx2x *bp = params->bp;
2200         u8 port = params->port;
2201         u16 val;
2202         u8 ext_phy_addr = ((params->ext_phy_config &
2203                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2204                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2205         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2206
2207         bnx2x_cl45_read(bp, params->port,
2208                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2209                       ext_phy_addr,
2210                       MDIO_PMA_DEVAD,
2211                       0xc801, &val);
2212
2213         if (val == 0) {
2214                 /* Mustn't set low power mode in 8073 A0 */
2215                 return;
2216         }
2217
2218         /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
2219         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2220                        MDIO_XS_DEVAD,
2221                        MDIO_XS_PLL_SEQUENCER, &val);
2222         val &= ~(1<<13);
2223         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2224                        MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2225
2226         /* PLL controls */
2227         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2228                        MDIO_XS_DEVAD, 0x805E, 0x1077);
2229         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2230                        MDIO_XS_DEVAD, 0x805D, 0x0000);
2231         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2232                        MDIO_XS_DEVAD, 0x805C, 0x030B);
2233         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2234                        MDIO_XS_DEVAD, 0x805B, 0x1240);
2235         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2236                        MDIO_XS_DEVAD, 0x805A, 0x2490);
2237
2238         /* Tx Controls */
2239         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2240                        MDIO_XS_DEVAD, 0x80A7, 0x0C74);
2241         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2242                        MDIO_XS_DEVAD, 0x80A6, 0x9041);
2243         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2244                        MDIO_XS_DEVAD, 0x80A5, 0x4640);
2245
2246         /* Rx Controls */
2247         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2248                        MDIO_XS_DEVAD, 0x80FE, 0x01C4);
2249         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2250                        MDIO_XS_DEVAD, 0x80FD, 0x9249);
2251         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2252                        MDIO_XS_DEVAD, 0x80FC, 0x2015);
2253
2254         /* Enable PLL sequencer  (use read-modify-write to set bit 13) */
2255         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2256                        MDIO_XS_DEVAD,
2257                        MDIO_XS_PLL_SEQUENCER, &val);
2258         val |= (1<<13);
2259         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2260                        MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2261 }
2262 static void bnx2x_bcm807x_force_10G(struct link_params *params)
2263 {
2264         struct bnx2x *bp = params->bp;
2265         u8 port = params->port;
2266         u8 ext_phy_addr = ((params->ext_phy_config &
2267                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2268                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2269         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2270
2271         /* Force KR or KX */
2272         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2273                        MDIO_PMA_DEVAD,
2274                        MDIO_PMA_REG_CTRL,
2275                        0x2040);
2276         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2277                        MDIO_PMA_DEVAD,
2278                        MDIO_PMA_REG_10G_CTRL2,
2279                        0x000b);
2280         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2281                        MDIO_PMA_DEVAD,
2282                        MDIO_PMA_REG_BCM_CTRL,
2283                        0x0000);
2284         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2285                        MDIO_AN_DEVAD,
2286                        MDIO_AN_REG_CTRL,
2287                        0x0000);
2288 }
2289
2290 static void bnx2x_ext_phy_set_pause(struct link_params *params,
2291                                   struct link_vars *vars)
2292 {
2293         struct bnx2x *bp = params->bp;
2294         u16 val;
2295         u8 ext_phy_addr = ((params->ext_phy_config &
2296                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2297                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2298         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2299
2300         /* read modify write pause advertizing */
2301         bnx2x_cl45_read(bp, params->port,
2302                       ext_phy_type,
2303                       ext_phy_addr,
2304                       MDIO_AN_DEVAD,
2305                       MDIO_AN_REG_ADV_PAUSE, &val);
2306
2307         val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
2308
2309         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2310
2311         if ((vars->ieee_fc &
2312             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
2313             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
2314                 val |=  MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
2315         }
2316         if ((vars->ieee_fc &
2317             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
2318             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
2319                 val |=
2320                  MDIO_AN_REG_ADV_PAUSE_PAUSE;
2321         }
2322         DP(NETIF_MSG_LINK,
2323                  "Ext phy AN advertize 0x%x\n", val);
2324         bnx2x_cl45_write(bp, params->port,
2325                        ext_phy_type,
2326                        ext_phy_addr,
2327                        MDIO_AN_DEVAD,
2328                        MDIO_AN_REG_ADV_PAUSE, val);
2329 }
2330
2331
2332 static void bnx2x_init_internal_phy(struct link_params *params,
2333                                 struct link_vars *vars)
2334 {
2335         struct bnx2x *bp = params->bp;
2336         u8 port = params->port;
2337         if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
2338                 u16 bank, rx_eq;
2339
2340                 rx_eq = ((params->serdes_config &
2341                           PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK) >>
2342                          PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT);
2343
2344                 DP(NETIF_MSG_LINK, "setting rx eq to 0x%x\n", rx_eq);
2345                 for (bank = MDIO_REG_BANK_RX0; bank <= MDIO_REG_BANK_RX_ALL;
2346                       bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0)) {
2347                         CL45_WR_OVER_CL22(bp, port,
2348                                               params->phy_addr,
2349                                               bank ,
2350                                               MDIO_RX0_RX_EQ_BOOST,
2351                                               ((rx_eq &
2352                                 MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK) |
2353                                 MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL));
2354                 }
2355
2356                 /* forced speed requested? */
2357                 if (vars->line_speed != SPEED_AUTO_NEG) {
2358                         DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
2359
2360                         /* disable autoneg */
2361                         bnx2x_set_autoneg(params, vars);
2362
2363                         /* program speed and duplex */
2364                         bnx2x_program_serdes(params, vars);
2365
2366                 } else { /* AN_mode */
2367                         DP(NETIF_MSG_LINK, "not SGMII, AN\n");
2368
2369                         /* AN enabled */
2370                         bnx2x_set_brcm_cl37_advertisment(params);
2371
2372                         /* program duplex & pause advertisement (for aneg) */
2373                         bnx2x_set_ieee_aneg_advertisment(params,
2374                                                        vars->ieee_fc);
2375
2376                         /* enable autoneg */
2377                         bnx2x_set_autoneg(params, vars);
2378
2379                         /* enable and restart AN */
2380                         bnx2x_restart_autoneg(params);
2381                 }
2382
2383         } else { /* SGMII mode */
2384                 DP(NETIF_MSG_LINK, "SGMII\n");
2385
2386                 bnx2x_initialize_sgmii_process(params, vars);
2387         }
2388 }
2389
2390 static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
2391 {
2392         struct bnx2x *bp = params->bp;
2393         u32 ext_phy_type;
2394         u8 ext_phy_addr;
2395         u16 cnt;
2396         u16 ctrl = 0;
2397         u16 val = 0;
2398         u8 rc = 0;
2399         if (vars->phy_flags & PHY_XGXS_FLAG) {
2400                 ext_phy_addr = ((params->ext_phy_config &
2401                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2402                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2403
2404                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2405                 /* Make sure that the soft reset is off (expect for the 8072:
2406                  * due to the lock, it will be done inside the specific
2407                  * handling)
2408                  */
2409                 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
2410                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
2411                    (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) &&
2412                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
2413                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
2414                         /* Wait for soft reset to get cleared upto 1 sec */
2415                         for (cnt = 0; cnt < 1000; cnt++) {
2416                                 bnx2x_cl45_read(bp, params->port,
2417                                               ext_phy_type,
2418                                               ext_phy_addr,
2419                                               MDIO_PMA_DEVAD,
2420                                               MDIO_PMA_REG_CTRL, &ctrl);
2421                                 if (!(ctrl & (1<<15)))
2422                                         break;
2423                                 msleep(1);
2424                         }
2425                         DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n",
2426                                  ctrl, cnt);
2427                 }
2428
2429                 switch (ext_phy_type) {
2430                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
2431                         break;
2432
2433                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
2434                         DP(NETIF_MSG_LINK, "XGXS 8705\n");
2435
2436                         bnx2x_cl45_write(bp, params->port,
2437                                        ext_phy_type,
2438                                        ext_phy_addr,
2439                                        MDIO_PMA_DEVAD,
2440                                        MDIO_PMA_REG_MISC_CTRL,
2441                                        0x8288);
2442                         bnx2x_cl45_write(bp, params->port,
2443                                        ext_phy_type,
2444                                        ext_phy_addr,
2445                                        MDIO_PMA_DEVAD,
2446                                        MDIO_PMA_REG_PHY_IDENTIFIER,
2447                                        0x7fbf);
2448                         bnx2x_cl45_write(bp, params->port,
2449                                        ext_phy_type,
2450                                        ext_phy_addr,
2451                                        MDIO_PMA_DEVAD,
2452                                        MDIO_PMA_REG_CMU_PLL_BYPASS,
2453                                        0x0100);
2454                         bnx2x_cl45_write(bp, params->port,
2455                                        ext_phy_type,
2456                                        ext_phy_addr,
2457                                        MDIO_WIS_DEVAD,
2458                                        MDIO_WIS_REG_LASI_CNTL, 0x1);
2459                         break;
2460
2461                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
2462                         DP(NETIF_MSG_LINK, "XGXS 8706\n");
2463
2464                         msleep(10);
2465                         /* Force speed */
2466                         /* First enable LASI */
2467                         bnx2x_cl45_write(bp, params->port,
2468                                        ext_phy_type,
2469                                        ext_phy_addr,
2470                                        MDIO_PMA_DEVAD,
2471                                        MDIO_PMA_REG_RX_ALARM_CTRL,
2472                                        0x0400);
2473                         bnx2x_cl45_write(bp, params->port,
2474                                        ext_phy_type,
2475                                        ext_phy_addr,
2476                                        MDIO_PMA_DEVAD,
2477                                        MDIO_PMA_REG_LASI_CTRL, 0x0004);
2478
2479                         if (params->req_line_speed == SPEED_10000) {
2480                                 DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
2481
2482                                 bnx2x_cl45_write(bp, params->port,
2483                                                ext_phy_type,
2484                                                ext_phy_addr,
2485                                                MDIO_PMA_DEVAD,
2486                                                MDIO_PMA_REG_DIGITAL_CTRL,
2487                                                0x400);
2488                         } else {
2489                                 /* Force 1Gbps using autoneg with 1G
2490                                 advertisment */
2491
2492                                 /* Allow CL37 through CL73 */
2493                                 DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
2494                                 bnx2x_cl45_write(bp, params->port,
2495                                                ext_phy_type,
2496                                                ext_phy_addr,
2497                                                MDIO_AN_DEVAD,
2498                                                MDIO_AN_REG_CL37_CL73,
2499                                                0x040c);
2500
2501                                 /* Enable Full-Duplex advertisment on CL37 */
2502                                 bnx2x_cl45_write(bp, params->port,
2503                                                ext_phy_type,
2504                                                ext_phy_addr,
2505                                                MDIO_AN_DEVAD,
2506                                                MDIO_AN_REG_CL37_FC_LP,
2507                                                0x0020);
2508                                 /* Enable CL37 AN */
2509                                 bnx2x_cl45_write(bp, params->port,
2510                                                ext_phy_type,
2511                                                ext_phy_addr,
2512                                                MDIO_AN_DEVAD,
2513                                                MDIO_AN_REG_CL37_AN,
2514                                                0x1000);
2515                                 /* 1G support */
2516                                 bnx2x_cl45_write(bp, params->port,
2517                                                ext_phy_type,
2518                                                ext_phy_addr,
2519                                                MDIO_AN_DEVAD,
2520                                                MDIO_AN_REG_ADV, (1<<5));
2521
2522                                 /* Enable clause 73 AN */
2523                                 bnx2x_cl45_write(bp, params->port,
2524                                                ext_phy_type,
2525                                                ext_phy_addr,
2526                                                MDIO_AN_DEVAD,
2527                                                MDIO_AN_REG_CTRL,
2528                                                0x1200);
2529
2530                         }
2531
2532                         break;
2533
2534                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
2535                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
2536                 {
2537                         u16 tmp1;
2538                         u16 rx_alarm_ctrl_val;
2539                         u16 lasi_ctrl_val;
2540                         if (ext_phy_type ==
2541                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
2542                                 rx_alarm_ctrl_val = 0x400;
2543                                 lasi_ctrl_val = 0x0004;
2544                         } else {
2545                                 /* In 8073, port1 is directed through emac0 and
2546                                  * port0 is directed through emac1
2547                                  */
2548                                 rx_alarm_ctrl_val = (1<<2);
2549                                 /*lasi_ctrl_val = 0x0005;*/
2550                                 lasi_ctrl_val = 0x0004;
2551                         }
2552
2553                         /* Wait for soft reset to get cleared upto 1 sec */
2554                         for (cnt = 0; cnt < 1000; cnt++) {
2555                                 bnx2x_cl45_read(bp, params->port,
2556                                               ext_phy_type,
2557                                               ext_phy_addr,
2558                                               MDIO_PMA_DEVAD,
2559                                               MDIO_PMA_REG_CTRL,
2560                                               &ctrl);
2561                                 if (!(ctrl & (1<<15)))
2562                                         break;
2563                                 msleep(1);
2564                         }
2565                         DP(NETIF_MSG_LINK,
2566                                 "807x control reg 0x%x (after %d ms)\n",
2567                                 ctrl, cnt);
2568
2569                         if (ext_phy_type ==
2570                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072){
2571                                 bnx2x_bcm8072_external_rom_boot(params);
2572                         } else {
2573                                 bnx2x_bcm8073_external_rom_boot(params);
2574                                 /* In case of 8073 with long xaui lines,
2575                                 don't set the 8073 xaui low power*/
2576                                 bnx2x_bcm8073_set_xaui_low_power_mode(params);
2577                         }
2578
2579                         /* enable LASI */
2580                         bnx2x_cl45_write(bp, params->port,
2581                                        ext_phy_type,
2582                                        ext_phy_addr,
2583                                        MDIO_PMA_DEVAD,
2584                                        MDIO_PMA_REG_RX_ALARM_CTRL,
2585                                        rx_alarm_ctrl_val);
2586
2587                         bnx2x_cl45_write(bp, params->port,
2588                                        ext_phy_type,
2589                                        ext_phy_addr,
2590                                        MDIO_PMA_DEVAD,
2591                                        MDIO_PMA_REG_LASI_CTRL,
2592                                        lasi_ctrl_val);
2593
2594                         bnx2x_cl45_read(bp, params->port,
2595                                       ext_phy_type,
2596                                       ext_phy_addr,
2597                                       MDIO_PMA_DEVAD,
2598                                       MDIO_PMA_REG_RX_ALARM, &tmp1);
2599
2600                         DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1):"
2601                                              "0x%x\n", tmp1);
2602
2603                         /* If this is forced speed, set to KR or KX
2604                          * (all other are not supported)
2605                          */
2606                         if (!(params->req_line_speed == SPEED_AUTO_NEG)) {
2607                         if (params->req_line_speed == SPEED_10000) {
2608                                         bnx2x_bcm807x_force_10G(params);
2609                                         DP(NETIF_MSG_LINK,
2610                                            "Forced speed 10G on 807X\n");
2611                                         break;
2612                                 } else if (params->req_line_speed ==
2613                                            SPEED_2500) {
2614                                         val = (1<<5);
2615                                         /* Note that 2.5G works only
2616                                         when used with 1G advertisment */
2617                                 } else
2618                                         val = (1<<5);
2619                         } else {
2620
2621                                 val = 0;
2622                                 if (params->speed_cap_mask &
2623                                         PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
2624                                         val |= (1<<7);
2625
2626                                 if (params->speed_cap_mask &
2627                                         PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
2628                                         val |= (1<<5);
2629                                 DP(NETIF_MSG_LINK, "807x autoneg val = 0x%x\n", val);
2630                                 /*val = ((1<<5)|(1<<7));*/
2631                         }
2632
2633                         bnx2x_cl45_write(bp, params->port,
2634                                        ext_phy_type,
2635                                        ext_phy_addr,
2636                                        MDIO_AN_DEVAD,
2637                                        MDIO_AN_REG_ADV, val);
2638
2639                         if (ext_phy_type ==
2640                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
2641                                 /* Disable 2.5Ghz */
2642                                 bnx2x_cl45_read(bp, params->port,
2643                                               ext_phy_type,
2644                                               ext_phy_addr,
2645                                               MDIO_AN_DEVAD,
2646                                               0x8329, &tmp1);
2647 /* SUPPORT_SPEED_CAPABILITY
2648                                 (Due to the nature of the link order, its not
2649                                 possible to enable 2.5G within the autoneg
2650                                 capabilities)
2651                                 if (params->speed_cap_mask &
2652                                 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
2653 */
2654                                 if (params->req_line_speed == SPEED_2500) {
2655                                         u16 phy_ver;
2656                                         /* Allow 2.5G for A1 and above */
2657                                         bnx2x_cl45_read(bp, params->port,
2658                                          PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2659                                          ext_phy_addr,
2660                                          MDIO_PMA_DEVAD,
2661                                          0xc801, &phy_ver);
2662
2663                                         if (phy_ver > 0)
2664                                                 tmp1 |= 1;
2665                                         else
2666                                                 tmp1 &= 0xfffe;
2667                         }
2668                                 else
2669                                         tmp1 &= 0xfffe;
2670
2671                         bnx2x_cl45_write(bp, params->port,
2672                                        ext_phy_type,
2673                                        ext_phy_addr,
2674                                        MDIO_AN_DEVAD,
2675                                                0x8329, tmp1);
2676                         }
2677                         /* Add support for CL37 (passive mode) I */
2678                         bnx2x_cl45_write(bp, params->port,
2679                                        ext_phy_type,
2680                                        ext_phy_addr,
2681                                        MDIO_AN_DEVAD,
2682                                        MDIO_AN_REG_CL37_FC_LD, 0x040c);
2683                         /* Add support for CL37 (passive mode) II */
2684                         bnx2x_cl45_write(bp, params->port,
2685                                        ext_phy_type,
2686                                        ext_phy_addr,
2687                                        MDIO_AN_DEVAD,
2688                                        MDIO_AN_REG_CL37_FC_LD, 0x20);
2689                         /* Add support for CL37 (passive mode) III */
2690                         bnx2x_cl45_write(bp, params->port,
2691                                        ext_phy_type,
2692                                        ext_phy_addr,
2693                                        MDIO_AN_DEVAD,
2694                                        MDIO_AN_REG_CL37_AN, 0x1000);
2695                         /* Restart autoneg */
2696                         msleep(500);
2697
2698                         if (ext_phy_type ==
2699                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
2700
2701                         /* The SNR will improve about 2db by changing the
2702                                 BW and FEE main tap. Rest commands are executed
2703                                 after link is up*/
2704                         /* Change FFE main cursor to 5 in EDC register */
2705                                 if (bnx2x_8073_is_snr_needed(params))
2706                                         bnx2x_cl45_write(bp, params->port,
2707                                                     ext_phy_type,
2708                                                     ext_phy_addr,
2709                                                     MDIO_PMA_DEVAD,
2710                                                     MDIO_PMA_REG_EDC_FFE_MAIN,
2711                                                     0xFB0C);
2712
2713                         /* Enable FEC (Forware Error Correction)
2714                            Request in the AN */
2715                         bnx2x_cl45_read(bp, params->port,
2716                                       ext_phy_type,
2717                                       ext_phy_addr,
2718                                       MDIO_AN_DEVAD,
2719                                       MDIO_AN_REG_ADV2, &tmp1);
2720
2721                         tmp1 |= (1<<15);
2722
2723                         bnx2x_cl45_write(bp, params->port,
2724                                       ext_phy_type,
2725                                       ext_phy_addr,
2726                                       MDIO_AN_DEVAD,
2727                                       MDIO_AN_REG_ADV2, tmp1);
2728                         }
2729
2730                         bnx2x_ext_phy_set_pause(params, vars);
2731
2732                         bnx2x_cl45_write(bp, params->port,
2733                                        ext_phy_type,
2734                                        ext_phy_addr,
2735                                        MDIO_AN_DEVAD,
2736                                        MDIO_AN_REG_CTRL, 0x1200);
2737                         DP(NETIF_MSG_LINK, "807x Autoneg Restart: "
2738                            "Advertise 1G=%x, 10G=%x\n",
2739                            ((val & (1<<5)) > 0),
2740                            ((val & (1<<7)) > 0));
2741                         break;
2742                 }
2743                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
2744                         DP(NETIF_MSG_LINK,
2745                                 "Setting the SFX7101 LASI indication\n");
2746
2747                         bnx2x_cl45_write(bp, params->port,
2748                                        ext_phy_type,
2749                                        ext_phy_addr,
2750                                        MDIO_PMA_DEVAD,
2751                                        MDIO_PMA_REG_LASI_CTRL, 0x1);
2752                         DP(NETIF_MSG_LINK,
2753                           "Setting the SFX7101 LED to blink on traffic\n");
2754                         bnx2x_cl45_write(bp, params->port,
2755                                        ext_phy_type,
2756                                        ext_phy_addr,
2757                                        MDIO_PMA_DEVAD,
2758                                        MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
2759
2760                         bnx2x_ext_phy_set_pause(params, vars);
2761                         /* Restart autoneg */
2762                         bnx2x_cl45_read(bp, params->port,
2763                                       ext_phy_type,
2764                                       ext_phy_addr,
2765                                       MDIO_AN_DEVAD,
2766                                       MDIO_AN_REG_CTRL, &val);
2767                         val |= 0x200;
2768                         bnx2x_cl45_write(bp, params->port,
2769                                        ext_phy_type,
2770                                        ext_phy_addr,
2771                                        MDIO_AN_DEVAD,
2772                                        MDIO_AN_REG_CTRL, val);
2773                         break;
2774                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
2775                         DP(NETIF_MSG_LINK,
2776                                  "XGXS PHY Failure detected 0x%x\n",
2777                                  params->ext_phy_config);
2778                         rc = -EINVAL;
2779                         break;
2780                 default:
2781                         DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
2782                                   params->ext_phy_config);
2783                         rc = -EINVAL;
2784                         break;
2785                 }
2786
2787         } else { /* SerDes */
2788
2789                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
2790                 switch (ext_phy_type) {
2791                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
2792                         DP(NETIF_MSG_LINK, "SerDes Direct\n");
2793                         break;
2794
2795                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
2796                         DP(NETIF_MSG_LINK, "SerDes 5482\n");
2797                         break;
2798
2799                 default:
2800                         DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
2801                            params->ext_phy_config);
2802                         break;
2803                 }
2804         }
2805         return rc;
2806 }
2807
2808
2809 static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
2810                                  struct link_vars *vars)
2811 {
2812         struct bnx2x *bp = params->bp;
2813         u32 ext_phy_type;
2814         u8 ext_phy_addr;
2815         u16 val1 = 0, val2;
2816         u16 rx_sd, pcs_status;
2817         u8 ext_phy_link_up = 0;
2818         u8 port = params->port;
2819         if (vars->phy_flags & PHY_XGXS_FLAG) {
2820                 ext_phy_addr = ((params->ext_phy_config &
2821                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2822                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2823
2824                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2825                 switch (ext_phy_type) {
2826                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
2827                         DP(NETIF_MSG_LINK, "XGXS Direct\n");
2828                         ext_phy_link_up = 1;
2829                         break;
2830
2831                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
2832                         DP(NETIF_MSG_LINK, "XGXS 8705\n");
2833                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
2834                                       ext_phy_addr,
2835                                       MDIO_WIS_DEVAD,
2836                                       MDIO_WIS_REG_LASI_STATUS, &val1);
2837                         DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
2838
2839                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
2840                                       ext_phy_addr,
2841                                       MDIO_WIS_DEVAD,
2842                                       MDIO_WIS_REG_LASI_STATUS, &val1);
2843                         DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
2844
2845                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
2846                                       ext_phy_addr,
2847                                       MDIO_PMA_DEVAD,
2848                                       MDIO_PMA_REG_RX_SD, &rx_sd);
2849                         DP(NETIF_MSG_LINK, "8705 rx_sd 0x%x\n", rx_sd);
2850                         ext_phy_link_up = (rx_sd & 0x1);
2851                         if (ext_phy_link_up)
2852                                 vars->line_speed = SPEED_10000;
2853                         break;
2854
2855                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
2856                         DP(NETIF_MSG_LINK, "XGXS 8706\n");
2857                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
2858                                       ext_phy_addr,
2859                                       MDIO_PMA_DEVAD,
2860                                       MDIO_PMA_REG_LASI_STATUS, &val1);
2861                         DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
2862
2863                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
2864                                       ext_phy_addr,
2865                                       MDIO_PMA_DEVAD,
2866                                       MDIO_PMA_REG_LASI_STATUS, &val1);
2867                         DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
2868
2869                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
2870                                       ext_phy_addr,
2871                                       MDIO_PMA_DEVAD,
2872                                       MDIO_PMA_REG_RX_SD, &rx_sd);
2873                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
2874                                       ext_phy_addr,
2875                                       MDIO_PCS_DEVAD,
2876                                       MDIO_PCS_REG_STATUS, &pcs_status);
2877
2878                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
2879                                       ext_phy_addr,
2880                                       MDIO_AN_DEVAD,
2881                                       MDIO_AN_REG_LINK_STATUS, &val2);
2882                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
2883                                       ext_phy_addr,
2884                                       MDIO_AN_DEVAD,
2885                                       MDIO_AN_REG_LINK_STATUS, &val2);
2886
2887                         DP(NETIF_MSG_LINK, "8706 rx_sd 0x%x"
2888                            "  pcs_status 0x%x 1Gbps link_status 0x%x\n",
2889                            rx_sd, pcs_status, val2);
2890                         /* link is up if both bit 0 of pmd_rx_sd and
2891                          * bit 0 of pcs_status are set, or if the autoneg bit
2892                            1 is set
2893                          */
2894                         ext_phy_link_up = ((rx_sd & pcs_status & 0x1) ||
2895                                            (val2 & (1<<1)));
2896                         if (ext_phy_link_up) {
2897                                 if (val2 & (1<<1))
2898                                         vars->line_speed = SPEED_1000;
2899                                 else
2900                                         vars->line_speed = SPEED_10000;
2901                         }
2902
2903                         /* clear LASI indication*/
2904                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
2905                                       ext_phy_addr,
2906                                       MDIO_PMA_DEVAD,
2907                                       MDIO_PMA_REG_RX_ALARM, &val2);
2908                         break;
2909
2910                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
2911                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
2912                 {
2913                         if (ext_phy_type ==
2914                              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
2915                                 bnx2x_cl45_read(bp, params->port,
2916                                       ext_phy_type,
2917                                       ext_phy_addr,
2918                                       MDIO_PCS_DEVAD,
2919                                       MDIO_PCS_REG_LASI_STATUS, &val1);
2920                         bnx2x_cl45_read(bp, params->port,
2921                                       ext_phy_type,
2922                                       ext_phy_addr,
2923                                       MDIO_PCS_DEVAD,
2924                                       MDIO_PCS_REG_LASI_STATUS, &val2);
2925                         DP(NETIF_MSG_LINK,
2926                                  "870x LASI status 0x%x->0x%x\n",
2927                                   val1, val2);
2928
2929                         } else {
2930                                 /* In 8073, port1 is directed through emac0 and
2931                                  * port0 is directed through emac1
2932                                  */
2933                                 bnx2x_cl45_read(bp, params->port,
2934                                               ext_phy_type,
2935                                               ext_phy_addr,
2936                                               MDIO_PMA_DEVAD,
2937                                               MDIO_PMA_REG_LASI_STATUS, &val1);
2938
2939                                 bnx2x_cl45_read(bp, params->port,
2940                                               ext_phy_type,
2941                                               ext_phy_addr,
2942                                               MDIO_PMA_DEVAD,
2943                                               MDIO_PMA_REG_LASI_STATUS, &val2);
2944                                 DP(NETIF_MSG_LINK,
2945                                          "8703 LASI status 0x%x->0x%x\n",
2946                                           val1, val2);
2947                         }
2948
2949                         /* clear the interrupt LASI status register */
2950                         bnx2x_cl45_read(bp, params->port,
2951                                       ext_phy_type,
2952                                       ext_phy_addr,
2953                                       MDIO_PCS_DEVAD,
2954                                       MDIO_PCS_REG_STATUS, &val2);
2955                         bnx2x_cl45_read(bp, params->port,
2956                                       ext_phy_type,
2957                                       ext_phy_addr,
2958                                       MDIO_PCS_DEVAD,
2959                                       MDIO_PCS_REG_STATUS, &val1);
2960                         DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n",
2961                            val2, val1);
2962                         /* Check the LASI */
2963                         bnx2x_cl45_read(bp, params->port,
2964                                       ext_phy_type,
2965                                       ext_phy_addr,
2966                                       MDIO_PMA_DEVAD,
2967                                       MDIO_PMA_REG_RX_ALARM, &val2);
2968                         bnx2x_cl45_read(bp, params->port,
2969                                       ext_phy_type,
2970                                       ext_phy_addr,
2971                                       MDIO_PMA_DEVAD,
2972                                       MDIO_PMA_REG_RX_ALARM,
2973                                       &val1);
2974                         DP(NETIF_MSG_LINK, "KR 0x9003 0x%x->0x%x\n",
2975                            val2, val1);
2976                         /* Check the link status */
2977                         bnx2x_cl45_read(bp, params->port,
2978                                       ext_phy_type,
2979                                       ext_phy_addr,
2980                                       MDIO_PCS_DEVAD,
2981                                       MDIO_PCS_REG_STATUS, &val2);
2982                         DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
2983
2984                         bnx2x_cl45_read(bp, params->port,
2985                                       ext_phy_type,
2986                                       ext_phy_addr,
2987                                       MDIO_PMA_DEVAD,
2988                                       MDIO_PMA_REG_STATUS, &val2);
2989                         bnx2x_cl45_read(bp, params->port,
2990                                       ext_phy_type,
2991                                       ext_phy_addr,
2992                                       MDIO_PMA_DEVAD,
2993                                       MDIO_PMA_REG_STATUS, &val1);
2994                         ext_phy_link_up = ((val1 & 4) == 4);
2995                         DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
2996                         if (ext_phy_type ==
2997                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
2998                                 u16 an1000_status = 0;
2999                                 if (ext_phy_link_up &&
3000                                     (
3001                                      (params->req_line_speed != SPEED_10000)
3002                                      )) {
3003                                         if (bnx2x_bcm8073_xaui_wa(params)
3004                                              != 0) {
3005                                                 ext_phy_link_up = 0;
3006                                                 break;
3007                                         }
3008                                         bnx2x_cl45_read(bp, params->port,
3009                                                       ext_phy_type,
3010                                                       ext_phy_addr,
3011                                                       MDIO_XS_DEVAD,
3012                                                       0x8304,
3013                                                       &an1000_status);
3014                                         bnx2x_cl45_read(bp, params->port,
3015                                                       ext_phy_type,
3016                                                       ext_phy_addr,
3017                                                       MDIO_XS_DEVAD,
3018                                                       0x8304,
3019                                                       &an1000_status);
3020                                 }
3021                                 /* Check the link status on 1.1.2 */
3022                                 bnx2x_cl45_read(bp, params->port,
3023                                               ext_phy_type,
3024                                               ext_phy_addr,
3025                                               MDIO_PMA_DEVAD,
3026                                               MDIO_PMA_REG_STATUS, &val2);
3027                                 bnx2x_cl45_read(bp, params->port,
3028                                               ext_phy_type,
3029                                               ext_phy_addr,
3030                                               MDIO_PMA_DEVAD,
3031                                               MDIO_PMA_REG_STATUS, &val1);
3032                                 DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
3033                                              "an_link_status=0x%x\n",
3034                                           val2, val1, an1000_status);
3035
3036                                 ext_phy_link_up = (((val1 & 4) == 4) ||
3037                                                     (an1000_status & (1<<1)));
3038                                 if (ext_phy_link_up &&
3039                                     bnx2x_8073_is_snr_needed(params)) {
3040                                         /* The SNR will improve about 2dbby
3041                                         changing the BW and FEE main tap.*/
3042
3043                                         /* The 1st write to change FFE main
3044                                         tap is set before restart AN */
3045                                         /* Change PLL Bandwidth in EDC
3046                                         register */
3047                                         bnx2x_cl45_write(bp, port, ext_phy_type,
3048                                                     ext_phy_addr,
3049                                                     MDIO_PMA_DEVAD,
3050                                                     MDIO_PMA_REG_PLL_BANDWIDTH,
3051                                                     0x26BC);
3052
3053                                         /* Change CDR Bandwidth in EDC
3054                                         register */
3055                                         bnx2x_cl45_write(bp, port, ext_phy_type,
3056                                                     ext_phy_addr,
3057                                                     MDIO_PMA_DEVAD,
3058                                                     MDIO_PMA_REG_CDR_BANDWIDTH,
3059                                                     0x0333);
3060
3061                                 }
3062                         }
3063                         break;
3064                 }
3065                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3066                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3067                                       ext_phy_addr,
3068                                       MDIO_PMA_DEVAD,
3069                                       MDIO_PMA_REG_LASI_STATUS, &val2);
3070                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3071                                       ext_phy_addr,
3072                                       MDIO_PMA_DEVAD,
3073                                       MDIO_PMA_REG_LASI_STATUS, &val1);
3074                         DP(NETIF_MSG_LINK,
3075                                  "10G-base-T LASI status 0x%x->0x%x\n",
3076                                   val2, val1);
3077                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3078                                       ext_phy_addr,
3079                                       MDIO_PMA_DEVAD,
3080                                       MDIO_PMA_REG_STATUS, &val2);
3081                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3082                                       ext_phy_addr,
3083                                       MDIO_PMA_DEVAD,
3084                                       MDIO_PMA_REG_STATUS, &val1);
3085                         DP(NETIF_MSG_LINK,
3086                                  "10G-base-T PMA status 0x%x->0x%x\n",
3087                                  val2, val1);
3088                         ext_phy_link_up = ((val1 & 4) == 4);
3089                         /* if link is up
3090                          * print the AN outcome of the SFX7101 PHY
3091                          */
3092                         if (ext_phy_link_up) {
3093                                 bnx2x_cl45_read(bp, params->port,
3094                                               ext_phy_type,
3095                                               ext_phy_addr,
3096                                               MDIO_AN_DEVAD,
3097                                               MDIO_AN_REG_MASTER_STATUS,
3098                                               &val2);
3099                                 vars->line_speed = SPEED_10000;
3100                                 DP(NETIF_MSG_LINK,
3101                                          "SFX7101 AN status 0x%x->Master=%x\n",
3102                                           val2,
3103                                          (val2 & (1<<14)));
3104                         }
3105                         break;
3106
3107                 default:
3108                         DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
3109                            params->ext_phy_config);
3110                         ext_phy_link_up = 0;
3111                         break;
3112                 }
3113
3114         } else { /* SerDes */
3115                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3116                 switch (ext_phy_type) {
3117                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
3118                         DP(NETIF_MSG_LINK, "SerDes Direct\n");
3119                         ext_phy_link_up = 1;
3120                         break;
3121
3122                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
3123                         DP(NETIF_MSG_LINK, "SerDes 5482\n");
3124                         ext_phy_link_up = 1;
3125                         break;
3126
3127                 default:
3128                         DP(NETIF_MSG_LINK,
3129                                  "BAD SerDes ext_phy_config 0x%x\n",
3130                                  params->ext_phy_config);
3131                         ext_phy_link_up = 0;
3132                         break;
3133                 }
3134         }
3135
3136         return ext_phy_link_up;
3137 }
3138
3139 static void bnx2x_link_int_enable(struct link_params *params)
3140 {
3141         u8 port = params->port;
3142         u32 ext_phy_type;
3143         u32 mask;
3144         struct bnx2x *bp = params->bp;
3145         /* setting the status to report on link up
3146            for either XGXS or SerDes */
3147
3148         if (params->switch_cfg == SWITCH_CFG_10G) {
3149                 mask = (NIG_MASK_XGXS0_LINK10G |
3150                         NIG_MASK_XGXS0_LINK_STATUS);
3151                 DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
3152                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3153                 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
3154                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
3155                     (ext_phy_type !=
3156                                 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) {
3157                         mask |= NIG_MASK_MI_INT;
3158                         DP(NETIF_MSG_LINK, "enabled external phy int\n");
3159                 }
3160
3161         } else { /* SerDes */
3162                 mask = NIG_MASK_SERDES0_LINK_STATUS;
3163                 DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
3164                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3165                 if ((ext_phy_type !=
3166                                 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
3167                     (ext_phy_type !=
3168                                 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) {
3169                         mask |= NIG_MASK_MI_INT;
3170                         DP(NETIF_MSG_LINK, "enabled external phy int\n");
3171                 }
3172         }
3173         bnx2x_bits_en(bp,
3174                       NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
3175                       mask);
3176         DP(NETIF_MSG_LINK, "port %x, is_xgxs=%x, int_status 0x%x\n", port,
3177                  (params->switch_cfg == SWITCH_CFG_10G),
3178                  REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
3179
3180         DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
3181                  REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
3182                  REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
3183                  REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
3184         DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
3185            REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
3186            REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
3187 }
3188
3189
3190 /*
3191  * link management
3192  */
3193 static void bnx2x_link_int_ack(struct link_params *params,
3194                              struct link_vars *vars, u16 is_10g)
3195 {
3196         struct bnx2x *bp = params->bp;
3197         u8 port = params->port;
3198
3199         /* first reset all status
3200          * we assume only one line will be change at a time */
3201         bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3202                      (NIG_STATUS_XGXS0_LINK10G |
3203                       NIG_STATUS_XGXS0_LINK_STATUS |
3204                       NIG_STATUS_SERDES0_LINK_STATUS));
3205         if (vars->phy_link_up) {
3206                 if (is_10g) {
3207                         /* Disable the 10G link interrupt
3208                          * by writing 1 to the status register
3209                          */
3210                         DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
3211                         bnx2x_bits_en(bp,
3212                                       NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3213                                       NIG_STATUS_XGXS0_LINK10G);
3214
3215                 } else if (params->switch_cfg == SWITCH_CFG_10G) {
3216                         /* Disable the link interrupt
3217                          * by writing 1 to the relevant lane
3218                          * in the status register
3219                          */
3220                         u32 ser_lane = ((params->lane_config &
3221                                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
3222                                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
3223
3224                         DP(NETIF_MSG_LINK, "1G XGXS phy link up\n");
3225                         bnx2x_bits_en(bp,
3226                                       NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3227                                       ((1 << ser_lane) <<
3228                                        NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
3229
3230                 } else { /* SerDes */
3231                         DP(NETIF_MSG_LINK, "SerDes phy link up\n");
3232                         /* Disable the link interrupt
3233                          * by writing 1 to the status register
3234                          */
3235                         bnx2x_bits_en(bp,
3236                                       NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3237                                       NIG_STATUS_SERDES0_LINK_STATUS);
3238                 }
3239
3240         } else { /* link_down */
3241         }
3242 }
3243
3244 static u8 bnx2x_format_ver(u32 num, u8 *str, u16 len)
3245 {
3246         u8 *str_ptr = str;
3247         u32 mask = 0xf0000000;
3248         u8 shift = 8*4;
3249         u8 digit;
3250         if (len < 10) {
3251                 /* Need more then 10chars for this format */
3252                 *str_ptr = '\0';
3253                 return -EINVAL;
3254         }
3255         while (shift > 0) {
3256
3257                 shift -= 4;
3258                 digit = ((num & mask) >> shift);
3259                 if (digit < 0xa)
3260                         *str_ptr = digit + '0';
3261                 else
3262                         *str_ptr = digit - 0xa + 'a';
3263                 str_ptr++;
3264                 mask = mask >> 4;
3265                 if (shift == 4*4) {
3266                         *str_ptr = ':';
3267                         str_ptr++;
3268                 }
3269         }
3270         *str_ptr = '\0';
3271         return 0;
3272 }
3273
3274
3275 static void bnx2x_turn_on_ef(struct bnx2x *bp, u8 port, u8 ext_phy_addr,
3276                            u32 ext_phy_type)
3277 {
3278         u32 cnt = 0;
3279         u16 ctrl = 0;
3280         /* Enable EMAC0 in to enable MDIO */
3281         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
3282                (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
3283         msleep(5);
3284
3285         /* take ext phy out of reset */
3286         bnx2x_set_gpio(bp,
3287                           MISC_REGISTERS_GPIO_2,
3288                           MISC_REGISTERS_GPIO_HIGH,
3289                           port);
3290
3291         bnx2x_set_gpio(bp,
3292                           MISC_REGISTERS_GPIO_1,
3293                           MISC_REGISTERS_GPIO_HIGH,
3294                           port);
3295
3296         /* wait for 5ms */
3297         msleep(5);
3298
3299         for (cnt = 0; cnt < 1000; cnt++) {
3300                 msleep(1);
3301                 bnx2x_cl45_read(bp, port,
3302                               ext_phy_type,
3303                               ext_phy_addr,
3304                               MDIO_PMA_DEVAD,
3305                               MDIO_PMA_REG_CTRL,
3306                                &ctrl);
3307                 if (!(ctrl & (1<<15))) {
3308                         DP(NETIF_MSG_LINK, "Reset completed\n\n");
3309                                 break;
3310                 }
3311         }
3312 }
3313
3314 static void bnx2x_turn_off_sf(struct bnx2x *bp, u8 port)
3315 {
3316         /* put sf to reset */
3317         bnx2x_set_gpio(bp,
3318                           MISC_REGISTERS_GPIO_1,
3319                           MISC_REGISTERS_GPIO_LOW,
3320                           port);
3321         bnx2x_set_gpio(bp,
3322                           MISC_REGISTERS_GPIO_2,
3323                           MISC_REGISTERS_GPIO_LOW,
3324                           port);
3325 }
3326
3327 u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
3328                               u8 *version, u16 len)
3329 {
3330         struct bnx2x *bp = params->bp;
3331         u32 ext_phy_type = 0;
3332         u16 val = 0;
3333         u8 ext_phy_addr = 0 ;
3334         u8 status = 0 ;
3335         u32 ver_num;
3336
3337         if (version == NULL || params == NULL)
3338                 return -EINVAL;
3339
3340         /* reset the returned value to zero */
3341         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3342         ext_phy_addr = ((params->ext_phy_config &
3343                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3344                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3345
3346         switch (ext_phy_type) {
3347         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3348
3349                 if (len < 5)
3350                         return -EINVAL;
3351
3352                 /* Take ext phy out of reset */
3353                 if (!driver_loaded)
3354                         bnx2x_turn_on_ef(bp, params->port, ext_phy_addr,
3355                                        ext_phy_type);
3356
3357                 /*  wait for 1ms */
3358                 msleep(1);
3359
3360                 bnx2x_cl45_read(bp, params->port,
3361                               ext_phy_type,
3362                               ext_phy_addr,
3363                               MDIO_PMA_DEVAD,
3364                               MDIO_PMA_REG_7101_VER1, &val);
3365                 version[2] = (val & 0xFF);
3366                 version[3] = ((val & 0xFF00)>>8);
3367
3368                 bnx2x_cl45_read(bp, params->port,
3369                               ext_phy_type,
3370                               ext_phy_addr,
3371                               MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2,
3372                               &val);
3373                 version[0] = (val & 0xFF);
3374                 version[1] = ((val & 0xFF00)>>8);
3375                 version[4] = '\0';
3376
3377                 if (!driver_loaded)
3378                         bnx2x_turn_off_sf(bp, params->port);
3379                 break;
3380         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3381         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
3382         {
3383                 /* Take ext phy out of reset */
3384                 if (!driver_loaded)
3385                         bnx2x_turn_on_ef(bp, params->port, ext_phy_addr,
3386                                        ext_phy_type);
3387
3388                 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3389                               ext_phy_addr,
3390                               MDIO_PMA_DEVAD,
3391                               MDIO_PMA_REG_ROM_VER1, &val);
3392                 ver_num = val<<16;
3393                 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3394                               ext_phy_addr,
3395                               MDIO_PMA_DEVAD,
3396                               MDIO_PMA_REG_ROM_VER2, &val);
3397                 ver_num |= val;
3398                 status = bnx2x_format_ver(ver_num, version, len);
3399                 break;
3400         }
3401         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
3402         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3403
3404                 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3405                               ext_phy_addr,
3406                               MDIO_PMA_DEVAD,
3407                               MDIO_PMA_REG_ROM_VER1, &val);
3408                 ver_num = val<<16;
3409                 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3410                               ext_phy_addr,
3411                               MDIO_PMA_DEVAD,
3412                               MDIO_PMA_REG_ROM_VER2, &val);
3413                 ver_num |= val;
3414                 status = bnx2x_format_ver(ver_num, version, len);
3415                 break;
3416
3417         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
3418                 break;
3419
3420         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
3421                 DP(NETIF_MSG_LINK, "bnx2x_get_ext_phy_fw_version:"
3422                                     " type is FAILURE!\n");
3423                 status = -EINVAL;
3424                 break;
3425
3426         default:
3427                 break;
3428         }
3429         return status;
3430 }
3431
3432 static void bnx2x_set_xgxs_loopback(struct link_params *params,
3433                                   struct link_vars *vars,
3434                                   u8 is_10g)
3435 {
3436         u8 port = params->port;
3437         struct bnx2x *bp = params->bp;
3438
3439         if (is_10g) {
3440                  u32 md_devad;
3441
3442                 DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
3443
3444                 /* change the uni_phy_addr in the nig */
3445                 md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
3446                                           port*0x18));
3447
3448                 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
3449
3450                 bnx2x_cl45_write(bp, port, 0,
3451                                params->phy_addr,
3452                                5,
3453                                (MDIO_REG_BANK_AER_BLOCK +
3454                                 (MDIO_AER_BLOCK_AER_REG & 0xf)),
3455                                0x2800);
3456
3457                 bnx2x_cl45_write(bp, port, 0,
3458                                params->phy_addr,
3459                                5,
3460                                (MDIO_REG_BANK_CL73_IEEEB0 +
3461                                 (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
3462                                0x6041);
3463
3464                 /* set aer mmd back */
3465                 bnx2x_set_aer_mmd(params, vars);
3466
3467                 /* and md_devad */
3468                 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
3469                             md_devad);
3470
3471         } else {
3472                 u16 mii_control;
3473
3474                 DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
3475
3476                 CL45_RD_OVER_CL22(bp, port,
3477                                       params->phy_addr,
3478                                       MDIO_REG_BANK_COMBO_IEEE0,
3479                                       MDIO_COMBO_IEEE0_MII_CONTROL,
3480                                       &mii_control);
3481
3482                 CL45_WR_OVER_CL22(bp, port,
3483                                       params->phy_addr,
3484                                       MDIO_REG_BANK_COMBO_IEEE0,
3485                                       MDIO_COMBO_IEEE0_MII_CONTROL,
3486                                       (mii_control |
3487                                        MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK));
3488         }
3489 }
3490
3491
3492 static void bnx2x_ext_phy_loopback(struct link_params *params)
3493 {
3494         struct bnx2x *bp = params->bp;
3495         u8 ext_phy_addr;
3496         u32 ext_phy_type;
3497
3498         if (params->switch_cfg == SWITCH_CFG_10G) {
3499                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3500                 /* CL37 Autoneg Enabled */
3501                 ext_phy_addr = ((params->ext_phy_config &
3502                                         PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3503                                         PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3504                 switch (ext_phy_type) {
3505                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
3506                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
3507                         DP(NETIF_MSG_LINK,
3508                                 "ext_phy_loopback: We should not get here\n");
3509                         break;
3510                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
3511                         DP(NETIF_MSG_LINK, "ext_phy_loopback: 8705\n");
3512                         break;
3513                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3514                         DP(NETIF_MSG_LINK, "ext_phy_loopback: 8706\n");
3515                         break;
3516                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3517                         /* SFX7101_XGXS_TEST1 */
3518                         bnx2x_cl45_write(bp, params->port, ext_phy_type,
3519                                        ext_phy_addr,
3520                                        MDIO_XS_DEVAD,
3521                                        MDIO_XS_SFX7101_XGXS_TEST1,
3522                                        0x100);
3523                         DP(NETIF_MSG_LINK,
3524                                 "ext_phy_loopback: set ext phy loopback\n");
3525                         break;
3526                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3527
3528                         break;
3529                 } /* switch external PHY type */
3530         } else {
3531                 /* serdes */
3532                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3533                 ext_phy_addr = (params->ext_phy_config  &
3534                 PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK)
3535                 >> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT;
3536         }
3537 }
3538
3539
3540 /*
3541  *------------------------------------------------------------------------
3542  * bnx2x_override_led_value -
3543  *
3544  * Override the led value of the requsted led
3545  *
3546  *------------------------------------------------------------------------
3547  */
3548 u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port,
3549                           u32 led_idx, u32 value)
3550 {
3551         u32 reg_val;
3552
3553         /* If port 0 then use EMAC0, else use EMAC1*/
3554         u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
3555
3556         DP(NETIF_MSG_LINK,
3557                  "bnx2x_override_led_value() port %x led_idx %d value %d\n",
3558                  port, led_idx, value);
3559
3560         switch (led_idx) {
3561         case 0: /* 10MB led */
3562                 /* Read the current value of the LED register in
3563                 the EMAC block */
3564                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
3565                 /* Set the OVERRIDE bit to 1 */
3566                 reg_val |= EMAC_LED_OVERRIDE;
3567                 /* If value is 1, set the 10M_OVERRIDE bit,
3568                 otherwise reset it.*/
3569                 reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) :
3570                         (reg_val & ~EMAC_LED_10MB_OVERRIDE);
3571                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3572                 break;
3573         case 1: /*100MB led    */
3574                 /*Read the current value of the LED register in
3575                 the EMAC block */
3576                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
3577                 /*  Set the OVERRIDE bit to 1 */
3578                 reg_val |= EMAC_LED_OVERRIDE;
3579                 /*  If value is 1, set the 100M_OVERRIDE bit,
3580                 otherwise reset it.*/
3581                 reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) :
3582                         (reg_val & ~EMAC_LED_100MB_OVERRIDE);
3583                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3584                 break;
3585         case 2: /* 1000MB led */
3586                 /* Read the current value of the LED register in the
3587                 EMAC block */
3588                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
3589                 /* Set the OVERRIDE bit to 1 */
3590                 reg_val |= EMAC_LED_OVERRIDE;
3591                 /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
3592                 reset it. */
3593                 reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) :
3594                         (reg_val & ~EMAC_LED_1000MB_OVERRIDE);
3595                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3596                 break;
3597         case 3: /* 2500MB led */
3598                 /*  Read the current value of the LED register in the
3599                 EMAC block*/
3600                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
3601                 /* Set the OVERRIDE bit to 1 */
3602                 reg_val |= EMAC_LED_OVERRIDE;
3603                 /*  If value is 1, set the 2500M_OVERRIDE bit, otherwise
3604                 reset it.*/
3605                 reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) :
3606                         (reg_val & ~EMAC_LED_2500MB_OVERRIDE);
3607                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3608                 break;
3609         case 4: /*10G led */
3610                 if (port == 0) {
3611                         REG_WR(bp, NIG_REG_LED_10G_P0,
3612                                     value);
3613                 } else {
3614                         REG_WR(bp, NIG_REG_LED_10G_P1,
3615                                     value);
3616                 }
3617                 break;
3618         case 5: /* TRAFFIC led */
3619                 /* Find if the traffic control is via BMAC or EMAC */
3620                 if (port == 0)
3621                         reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN);
3622                 else
3623                         reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN);
3624
3625                 /*  Override the traffic led in the EMAC:*/
3626                 if (reg_val == 1) {
3627                         /* Read the current value of the LED register in
3628                         the EMAC block */
3629                         reg_val = REG_RD(bp, emac_base +
3630                                              EMAC_REG_EMAC_LED);
3631                         /* Set the TRAFFIC_OVERRIDE bit to 1 */
3632                         reg_val |= EMAC_LED_OVERRIDE;
3633                         /* If value is 1, set the TRAFFIC bit, otherwise
3634                         reset it.*/
3635                         reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) :
3636                                 (reg_val & ~EMAC_LED_TRAFFIC);
3637                         REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3638                 } else { /* Override the traffic led in the BMAC: */
3639                         REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
3640                                    + port*4, 1);
3641                         REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4,
3642                                     value);
3643                 }
3644                 break;
3645         default:
3646                 DP(NETIF_MSG_LINK,
3647                          "bnx2x_override_led_value() unknown led index %d "
3648                          "(should be 0-5)\n", led_idx);
3649                 return -EINVAL;
3650         }
3651
3652         return 0;
3653 }
3654
3655
3656 u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed,
3657                u16 hw_led_mode, u32 chip_id)
3658 {
3659         u8 rc = 0;
3660         DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
3661         DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
3662                  speed, hw_led_mode);
3663         switch (mode) {
3664         case LED_MODE_OFF:
3665                 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
3666                 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
3667                            SHARED_HW_CFG_LED_MAC1);
3668                 break;
3669
3670         case LED_MODE_OPER:
3671                 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode);
3672                 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 +
3673                            port*4, 0);
3674                 /* Set blinking rate to ~15.9Hz */
3675                 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
3676                            LED_BLINK_RATE_VAL);
3677                 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
3678                            port*4, 1);
3679                 if (!CHIP_IS_E1H(bp) &&
3680                     ((speed == SPEED_2500) ||
3681                      (speed == SPEED_1000) ||
3682                      (speed == SPEED_100) ||
3683                      (speed == SPEED_10))) {
3684                         /* On Everest 1 Ax chip versions for speeds less than
3685                         10G LED scheme is different */
3686                         REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
3687                                    + port*4, 1);
3688                         REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
3689                                    port*4, 0);
3690                         REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
3691                                    port*4, 1);
3692                 }
3693                 break;
3694
3695         default:
3696                 rc = -EINVAL;
3697                 DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
3698                          mode);
3699                 break;
3700         }
3701         return rc;
3702
3703 }
3704
3705 u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars)
3706 {
3707         struct bnx2x *bp = params->bp;
3708         u16 gp_status = 0;
3709
3710         CL45_RD_OVER_CL22(bp, params->port,
3711                               params->phy_addr,
3712                               MDIO_REG_BANK_GP_STATUS,
3713                               MDIO_GP_STATUS_TOP_AN_STATUS1,
3714                               &gp_status);
3715         /* link is up only if both local phy and external phy are up */
3716         if ((gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) &&
3717             bnx2x_ext_phy_is_link_up(params, vars))
3718                 return 0;
3719
3720         return -ESRCH;
3721 }
3722
3723 static u8 bnx2x_link_initialize(struct link_params *params,
3724                               struct link_vars *vars)
3725 {
3726         struct bnx2x *bp = params->bp;
3727         u8 port = params->port;
3728         u8 rc = 0;
3729         u8 non_ext_phy;
3730         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3731         /* Activate the external PHY */
3732         bnx2x_ext_phy_reset(params, vars);
3733
3734         bnx2x_set_aer_mmd(params, vars);
3735
3736         if (vars->phy_flags & PHY_XGXS_FLAG)
3737                 bnx2x_set_master_ln(params);
3738
3739         rc = bnx2x_reset_unicore(params);
3740         /* reset the SerDes and wait for reset bit return low */
3741         if (rc != 0)
3742                 return rc;
3743
3744         bnx2x_set_aer_mmd(params, vars);
3745
3746         /* setting the masterLn_def again after the reset */
3747         if (vars->phy_flags & PHY_XGXS_FLAG) {
3748                 bnx2x_set_master_ln(params);
3749                 bnx2x_set_swap_lanes(params);
3750         }
3751
3752         if (vars->phy_flags & PHY_XGXS_FLAG) {
3753                 if (params->req_line_speed &&
3754                     ((params->req_line_speed == SPEED_100) ||
3755                      (params->req_line_speed == SPEED_10))) {
3756                         vars->phy_flags |= PHY_SGMII_FLAG;
3757                 } else {
3758                         vars->phy_flags &= ~PHY_SGMII_FLAG;
3759                 }
3760         }
3761         /* In case of external phy existance, the line speed would be the
3762          line speed linked up by the external phy. In case it is direct only,
3763           then the line_speed during initialization will be equal to the
3764            req_line_speed*/
3765         vars->line_speed = params->req_line_speed;
3766
3767         bnx2x_calc_ieee_aneg_adv(params, &vars->ieee_fc);
3768
3769         /* init ext phy and enable link state int */
3770         non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
3771                        (params->loopback_mode == LOOPBACK_XGXS_10) ||
3772                        (params->loopback_mode == LOOPBACK_EXT_PHY));
3773
3774         if (non_ext_phy ||
3775             (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705)) {
3776                 if (params->req_line_speed == SPEED_AUTO_NEG)
3777                         bnx2x_set_parallel_detection(params, vars->phy_flags);
3778                 bnx2x_init_internal_phy(params, vars);
3779         }
3780
3781         if (!non_ext_phy)
3782                 rc |= bnx2x_ext_phy_init(params, vars);
3783
3784         bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3785                      (NIG_STATUS_XGXS0_LINK10G |
3786                       NIG_STATUS_XGXS0_LINK_STATUS |
3787                       NIG_STATUS_SERDES0_LINK_STATUS));
3788
3789         return rc;
3790
3791 }
3792
3793
3794 u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
3795 {
3796         struct bnx2x *bp = params->bp;
3797
3798         u32 val;
3799         DP(NETIF_MSG_LINK, "Phy Initialization started\n");
3800         DP(NETIF_MSG_LINK, "req_speed = %d, req_flowctrl=%d\n",
3801                   params->req_line_speed, params->req_flow_ctrl);
3802         vars->link_status = 0;
3803         vars->phy_link_up = 0;
3804         vars->link_up = 0;
3805         vars->line_speed = 0;
3806         vars->duplex = DUPLEX_FULL;
3807         vars->flow_ctrl = FLOW_CTRL_NONE;
3808         vars->mac_type = MAC_TYPE_NONE;
3809
3810         if (params->switch_cfg ==  SWITCH_CFG_1G)
3811                 vars->phy_flags = PHY_SERDES_FLAG;
3812         else
3813                 vars->phy_flags = PHY_XGXS_FLAG;
3814
3815         /* disable attentions */
3816         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
3817                        (NIG_MASK_XGXS0_LINK_STATUS |
3818                         NIG_MASK_XGXS0_LINK10G |
3819                         NIG_MASK_SERDES0_LINK_STATUS |
3820                         NIG_MASK_MI_INT));
3821
3822         bnx2x_emac_init(params, vars);
3823
3824         if (CHIP_REV_IS_FPGA(bp)) {
3825                 vars->link_up = 1;
3826                 vars->line_speed = SPEED_10000;
3827                 vars->duplex = DUPLEX_FULL;
3828                 vars->flow_ctrl = FLOW_CTRL_NONE;
3829                 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
3830                 /* enable on E1.5 FPGA */
3831                 if (CHIP_IS_E1H(bp)) {
3832                         vars->flow_ctrl |=
3833                                 (FLOW_CTRL_TX | FLOW_CTRL_RX);
3834                         vars->link_status |=
3835                                         (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
3836                                          LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
3837                 }
3838
3839                 bnx2x_emac_enable(params, vars, 0);
3840                 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
3841                 /* disable drain */
3842                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
3843                                     + params->port*4, 0);
3844
3845                 /* update shared memory */
3846                 bnx2x_update_mng(params, vars->link_status);
3847
3848                 return 0;
3849
3850         } else
3851         if (CHIP_REV_IS_EMUL(bp)) {
3852
3853                 vars->link_up = 1;
3854                 vars->line_speed = SPEED_10000;
3855                 vars->duplex = DUPLEX_FULL;
3856                 vars->flow_ctrl = FLOW_CTRL_NONE;
3857                 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
3858
3859                 bnx2x_bmac_enable(params, vars, 0);
3860
3861                 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
3862                 /* Disable drain */
3863                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
3864                                     + params->port*4, 0);
3865
3866                 /* update shared memory */
3867                 bnx2x_update_mng(params, vars->link_status);
3868
3869                 return 0;
3870
3871         } else
3872         if (params->loopback_mode == LOOPBACK_BMAC) {
3873                 vars->link_up = 1;
3874                 vars->line_speed = SPEED_10000;
3875                 vars->duplex = DUPLEX_FULL;
3876                 vars->flow_ctrl = FLOW_CTRL_NONE;
3877                 vars->mac_type = MAC_TYPE_BMAC;
3878
3879                 vars->phy_flags = PHY_XGXS_FLAG;
3880
3881                 bnx2x_phy_deassert(params, vars->phy_flags);
3882                 /* set bmac loopback */
3883                 bnx2x_bmac_enable(params, vars, 1);
3884
3885                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
3886                     params->port*4, 0);
3887         } else if (params->loopback_mode == LOOPBACK_EMAC) {
3888                 vars->link_up = 1;
3889                 vars->line_speed = SPEED_1000;
3890                 vars->duplex = DUPLEX_FULL;
3891                 vars->flow_ctrl = FLOW_CTRL_NONE;
3892                 vars->mac_type = MAC_TYPE_EMAC;
3893
3894                 vars->phy_flags = PHY_XGXS_FLAG;
3895
3896                 bnx2x_phy_deassert(params, vars->phy_flags);
3897                 /* set bmac loopback */
3898                 bnx2x_emac_enable(params, vars, 1);
3899                 bnx2x_emac_program(params, vars->line_speed,
3900                                               vars->duplex);
3901                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
3902                     params->port*4, 0);
3903         } else if ((params->loopback_mode == LOOPBACK_XGXS_10) ||
3904                   (params->loopback_mode == LOOPBACK_EXT_PHY)) {
3905                 vars->link_up = 1;
3906                 vars->line_speed = SPEED_10000;
3907                 vars->duplex = DUPLEX_FULL;
3908                 vars->flow_ctrl = FLOW_CTRL_NONE;
3909
3910                 vars->phy_flags = PHY_XGXS_FLAG;
3911
3912                 val = REG_RD(bp,
3913                                  NIG_REG_XGXS0_CTRL_PHY_ADDR+
3914                                  params->port*0x18);
3915                 params->phy_addr = (u8)val;
3916
3917                 bnx2x_phy_deassert(params, vars->phy_flags);
3918                 bnx2x_link_initialize(params, vars);
3919
3920                 vars->mac_type = MAC_TYPE_BMAC;
3921
3922                 bnx2x_bmac_enable(params, vars, 0);
3923
3924                 if (params->loopback_mode == LOOPBACK_XGXS_10) {
3925                         /* set 10G XGXS loopback */
3926                         bnx2x_set_xgxs_loopback(params, vars, 1);
3927                 } else {
3928                         /* set external phy loopback */
3929                         bnx2x_ext_phy_loopback(params);
3930                 }
3931                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
3932                             params->port*4, 0);
3933         } else
3934         /* No loopback */
3935         {
3936
3937                 bnx2x_phy_deassert(params, vars->phy_flags);
3938                 switch (params->switch_cfg) {
3939                 case SWITCH_CFG_1G:
3940                         vars->phy_flags |= PHY_SERDES_FLAG;
3941                         if ((params->ext_phy_config &
3942                              PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) ==
3943                              PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482) {
3944                                 vars->phy_flags |=
3945                                         PHY_SGMII_FLAG;
3946                         }
3947
3948                         val = REG_RD(bp,
3949                                          NIG_REG_SERDES0_CTRL_PHY_ADDR+
3950                                          params->port*0x10);
3951
3952                         params->phy_addr = (u8)val;
3953
3954                         break;
3955                 case SWITCH_CFG_10G:
3956                         vars->phy_flags |= PHY_XGXS_FLAG;
3957                         val = REG_RD(bp,
3958                                  NIG_REG_XGXS0_CTRL_PHY_ADDR+
3959                                  params->port*0x18);
3960                         params->phy_addr = (u8)val;
3961
3962                         break;
3963                 default:
3964                         DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
3965                         return -EINVAL;
3966                         break;
3967                 }
3968
3969                 bnx2x_link_initialize(params, vars);
3970                 msleep(30);
3971                 bnx2x_link_int_enable(params);
3972         }
3973         return 0;
3974 }
3975
3976 u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars)
3977 {
3978
3979         struct bnx2x *bp = params->bp;
3980         u32 ext_phy_config = params->ext_phy_config;
3981         u16 hw_led_mode = params->hw_led_mode;
3982         u32 chip_id = params->chip_id;
3983         u8 port = params->port;
3984         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
3985         /* disable attentions */
3986
3987         vars->link_status = 0;
3988         bnx2x_update_mng(params, vars->link_status);
3989         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
3990                      (NIG_MASK_XGXS0_LINK_STATUS |
3991                       NIG_MASK_XGXS0_LINK10G |
3992                       NIG_MASK_SERDES0_LINK_STATUS |
3993                       NIG_MASK_MI_INT));
3994
3995         /* activate nig drain */
3996         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
3997
3998         /* disable nig egress interface */
3999         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
4000         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
4001
4002         /* Stop BigMac rx */
4003         bnx2x_bmac_rx_disable(bp, port);
4004
4005         /* disable emac */
4006         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
4007
4008         msleep(10);
4009         /* The PHY reset is controled by GPIO 1
4010          * Hold it as vars low
4011          */
4012          /* clear link led */
4013         bnx2x_set_led(bp, port, LED_MODE_OFF, 0, hw_led_mode, chip_id);
4014         if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
4015                 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
4016                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
4017                         /* HW reset */
4018
4019                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
4020                                           MISC_REGISTERS_GPIO_OUTPUT_LOW,
4021                                           port);
4022
4023                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4024                                           MISC_REGISTERS_GPIO_OUTPUT_LOW,
4025                                           port);
4026
4027                         DP(NETIF_MSG_LINK, "reset external PHY\n");
4028                 } else if (ext_phy_type ==
4029                            PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
4030                                 DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
4031                                          "low power mode\n",
4032                                          port);
4033                                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4034                                         MISC_REGISTERS_GPIO_OUTPUT_LOW,
4035                                                   port);
4036                 }
4037         }
4038         /* reset the SerDes/XGXS */
4039         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
4040                (0x1ff << (port*16)));
4041
4042         /* reset BigMac */
4043         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
4044                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4045
4046         /* disable nig ingress interface */
4047         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
4048         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
4049         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
4050         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
4051         vars->link_up = 0;
4052         return 0;
4053 }
4054
4055 static u8 bnx2x_update_link_down(struct link_params *params,
4056                                struct link_vars *vars)
4057 {
4058         struct bnx2x *bp = params->bp;
4059         u8 port = params->port;
4060         DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
4061         bnx2x_set_led(bp, port, LED_MODE_OFF,
4062                     0, params->hw_led_mode,
4063                     params->chip_id);
4064
4065         /* indicate no mac active */
4066         vars->mac_type = MAC_TYPE_NONE;
4067
4068         /* update shared memory */
4069         vars->link_status = 0;
4070         vars->line_speed = 0;
4071         bnx2x_update_mng(params, vars->link_status);
4072
4073         /* activate nig drain */
4074         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
4075
4076         /* reset BigMac */
4077         bnx2x_bmac_rx_disable(bp, params->port);
4078         REG_WR(bp, GRCBASE_MISC +
4079                    MISC_REGISTERS_RESET_REG_2_CLEAR,
4080                    (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4081         return 0;
4082 }
4083
4084 static u8 bnx2x_update_link_up(struct link_params *params,
4085                              struct link_vars *vars,
4086                              u8 link_10g, u32 gp_status)
4087 {
4088         struct bnx2x *bp = params->bp;
4089         u8 port = params->port;
4090         u8 rc = 0;
4091         vars->link_status |= LINK_STATUS_LINK_UP;
4092         if (link_10g) {
4093                 bnx2x_bmac_enable(params, vars, 0);
4094                 bnx2x_set_led(bp, port, LED_MODE_OPER,
4095                             SPEED_10000, params->hw_led_mode,
4096                             params->chip_id);
4097
4098         } else {
4099                 bnx2x_emac_enable(params, vars, 0);
4100                 rc = bnx2x_emac_program(params, vars->line_speed,
4101                                       vars->duplex);
4102
4103                 /* AN complete? */
4104                 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
4105                         if (!(vars->phy_flags &
4106                               PHY_SGMII_FLAG))
4107                                 bnx2x_set_sgmii_tx_driver(params);
4108                 }
4109         }
4110
4111         /* PBF - link up */
4112         rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
4113                               vars->line_speed);
4114
4115         /* disable drain */
4116         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
4117
4118         /* update shared memory */
4119         bnx2x_update_mng(params, vars->link_status);
4120         return rc;
4121 }
4122 /* This function should called upon link interrupt */
4123 /* In case vars->link_up, driver needs to
4124         1. Update the pbf
4125         2. Disable drain
4126         3. Update the shared memory
4127         4. Indicate link up
4128         5. Set LEDs
4129    Otherwise,
4130         1. Update shared memory
4131         2. Reset BigMac
4132         3. Report link down
4133         4. Unset LEDs
4134 */
4135 u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
4136 {
4137         struct bnx2x *bp = params->bp;
4138         u8 port = params->port;
4139         u16 gp_status;
4140         u8 link_10g;
4141         u8 ext_phy_link_up, rc = 0;
4142         u32 ext_phy_type;
4143
4144         DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
4145          port,
4146         (vars->phy_flags & PHY_XGXS_FLAG),
4147          REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
4148
4149         DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
4150         REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
4151         REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
4152         REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
4153
4154         DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
4155           REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
4156           REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
4157
4158         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4159
4160         /* Check external link change only for non-direct */
4161         ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars);
4162
4163         /* Read gp_status */
4164         CL45_RD_OVER_CL22(bp, port, params->phy_addr,
4165                               MDIO_REG_BANK_GP_STATUS,
4166                               MDIO_GP_STATUS_TOP_AN_STATUS1,
4167                               &gp_status);
4168
4169         rc = bnx2x_link_settings_status(params, vars, gp_status);
4170         if (rc != 0)
4171                 return rc;
4172
4173         /* anything 10 and over uses the bmac */
4174         link_10g = ((vars->line_speed == SPEED_10000) ||
4175                     (vars->line_speed == SPEED_12000) ||
4176                     (vars->line_speed == SPEED_12500) ||
4177                     (vars->line_speed == SPEED_13000) ||
4178                     (vars->line_speed == SPEED_15000) ||
4179                     (vars->line_speed == SPEED_16000));
4180
4181         bnx2x_link_int_ack(params, vars, link_10g);
4182
4183         /* In case external phy link is up, and internal link is down
4184         ( not initialized yet probably after link initialization, it needs
4185         to be initialized.
4186         Note that after link down-up as result of cable plug,
4187         the xgxs link would probably become up again without the need to
4188         initialize it*/
4189
4190         if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
4191             (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
4192             (ext_phy_link_up && !vars->phy_link_up))
4193                 bnx2x_init_internal_phy(params, vars);
4194
4195         /* link is up only if both local phy and external phy are up */
4196         vars->link_up = (ext_phy_link_up && vars->phy_link_up);
4197
4198         if (vars->link_up)
4199                 rc = bnx2x_update_link_up(params, vars, link_10g, gp_status);
4200         else
4201                 rc = bnx2x_update_link_down(params, vars);
4202
4203         return rc;
4204 }
4205
4206 static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
4207 {
4208         u16 val, cnt;
4209
4210         bnx2x_cl45_read(bp, port,
4211                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4212                       phy_addr,
4213                       MDIO_PMA_DEVAD,
4214                       MDIO_PMA_REG_7101_RESET, &val);
4215
4216         for (cnt = 0; cnt < 10; cnt++) {
4217                 msleep(50);
4218                 /* Writes a self-clearing reset */
4219                 bnx2x_cl45_write(bp, port,
4220                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4221                                phy_addr,
4222                                MDIO_PMA_DEVAD,
4223                                MDIO_PMA_REG_7101_RESET,
4224                                (val | (1<<15)));
4225                 /* Wait for clear */
4226                 bnx2x_cl45_read(bp, port,
4227                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4228                               phy_addr,
4229                               MDIO_PMA_DEVAD,
4230                               MDIO_PMA_REG_7101_RESET, &val);
4231
4232                 if ((val & (1<<15)) == 0)
4233                         break;
4234         }
4235 }
4236 #define RESERVED_SIZE 256
4237 /* max application is 160K bytes - data at end of RAM */
4238 #define MAX_APP_SIZE 160*1024 - RESERVED_SIZE
4239
4240 /* Header is 14 bytes */
4241 #define HEADER_SIZE 14
4242 #define DATA_OFFSET HEADER_SIZE
4243
4244 #define SPI_START_TRANSFER(bp, port, ext_phy_addr) \
4245         bnx2x_cl45_write(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, \
4246                         ext_phy_addr, \
4247                         MDIO_PCS_DEVAD, \
4248                         MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 1)
4249
4250 /* Programs an image to DSP's flash via the SPI port*/
4251 static u8 bnx2x_sfx7101_flash_download(struct bnx2x *bp, u8 port,
4252                                      u8 ext_phy_addr,
4253                                      char data[], u32 size)
4254 {
4255         const u16 num_trans = size/4; /* 4 bytes can be sent at a time */
4256         /* Doesn't include last trans!*/
4257         const u16 last_trans_size = size%4; /* Num bytes on last trans */
4258         u16 trans_cnt, byte_cnt;
4259         u32 data_index;
4260         u16 tmp;
4261         u16 code_started = 0;
4262         u16 image_revision1, image_revision2;
4263         u16 cnt;
4264
4265         DP(NETIF_MSG_LINK, "bnx2x_sfx7101_flash_download file_size=%d\n", size);
4266         /* Going to flash*/
4267         if ((size-HEADER_SIZE) > MAX_APP_SIZE) {
4268                 /* This very often will be the case, because the image is built
4269                 with 160Kbytes size whereas the total image size must actually
4270                 be 160Kbytes-RESERVED_SIZE */
4271                 DP(NETIF_MSG_LINK, "Warning, file size was %d bytes "
4272                          "truncated to %d bytes\n", size, MAX_APP_SIZE);
4273                 size = MAX_APP_SIZE+HEADER_SIZE;
4274         }
4275         DP(NETIF_MSG_LINK, "File version is %c%c\n", data[0x14e], data[0x14f]);
4276         DP(NETIF_MSG_LINK, "                %c%c\n", data[0x150], data[0x151]);
4277         /* Put the DSP in download mode by setting FLASH_CFG[2] to 1
4278            and issuing a reset.*/
4279
4280         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
4281                           MISC_REGISTERS_GPIO_HIGH, port);
4282
4283         bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
4284
4285         /* wait 0.5 sec */
4286         for (cnt = 0; cnt < 100; cnt++)
4287                 msleep(5);
4288
4289         /* Make sure we can access the DSP
4290            And it's in the correct mode (waiting for download) */
4291
4292         bnx2x_cl45_read(bp, port,
4293                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4294                       ext_phy_addr,
4295                       MDIO_PCS_DEVAD,
4296                       MDIO_PCS_REG_7101_DSP_ACCESS, &tmp);
4297
4298         if (tmp != 0x000A) {
4299                 DP(NETIF_MSG_LINK, "DSP is not in waiting on download mode. "
4300                          "Expected 0x000A, read 0x%04X\n", tmp);
4301                 DP(NETIF_MSG_LINK, "Download failed\n");
4302                 return -EINVAL;
4303         }
4304
4305         /* Mux the SPI interface away from the internal processor */
4306         bnx2x_cl45_write(bp, port,
4307                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4308                        ext_phy_addr,
4309                        MDIO_PCS_DEVAD,
4310                        MDIO_PCS_REG_7101_SPI_MUX, 1);
4311
4312         /* Reset the SPI port */
4313         bnx2x_cl45_write(bp, port,
4314                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4315                        ext_phy_addr,
4316                        MDIO_PCS_DEVAD,
4317                        MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
4318         bnx2x_cl45_write(bp, port,
4319                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4320                        ext_phy_addr,
4321                        MDIO_PCS_DEVAD,
4322                        MDIO_PCS_REG_7101_SPI_CTRL_ADDR,
4323                        (1<<MDIO_PCS_REG_7101_SPI_RESET_BIT));
4324         bnx2x_cl45_write(bp, port,
4325                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4326                        ext_phy_addr,
4327                        MDIO_PCS_DEVAD,
4328                        MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
4329
4330         /* Erase the flash */
4331         bnx2x_cl45_write(bp, port,
4332                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4333                        ext_phy_addr,
4334                        MDIO_PCS_DEVAD,
4335                        MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4336                        MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
4337
4338         bnx2x_cl45_write(bp, port,
4339                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4340                        ext_phy_addr,
4341                        MDIO_PCS_DEVAD,
4342                        MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4343                        1);
4344
4345         SPI_START_TRANSFER(bp, port, ext_phy_addr);
4346         bnx2x_cl45_write(bp, port,
4347                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4348                        ext_phy_addr,
4349                        MDIO_PCS_DEVAD,
4350                        MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4351                        MDIO_PCS_REG_7101_SPI_FIFO_ADDR_BULK_ERASE_CMD);
4352
4353         bnx2x_cl45_write(bp, port,
4354                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4355                        ext_phy_addr,
4356                        MDIO_PCS_DEVAD,
4357                        MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4358                        1);
4359         SPI_START_TRANSFER(bp, port, ext_phy_addr);
4360
4361         /* Wait 10 seconds, the maximum time for the erase to complete */
4362         DP(NETIF_MSG_LINK, "Erasing flash, this takes 10 seconds...\n");
4363         for (cnt = 0; cnt < 1000; cnt++)
4364                 msleep(10);
4365
4366         DP(NETIF_MSG_LINK, "Downloading flash, please wait...\n");
4367         data_index = 0;
4368         for (trans_cnt = 0; trans_cnt < num_trans; trans_cnt++) {
4369                 bnx2x_cl45_write(bp, port,
4370                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4371                              ext_phy_addr,
4372                              MDIO_PCS_DEVAD,
4373                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4374                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
4375
4376                 bnx2x_cl45_write(bp, port,
4377                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4378                                ext_phy_addr,
4379                                MDIO_PCS_DEVAD,
4380                                MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4381                                1);
4382                 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4383
4384                 bnx2x_cl45_write(bp, port,
4385                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4386                                ext_phy_addr,
4387                                MDIO_PCS_DEVAD,
4388                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4389                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
4390
4391                 /* Bits 23-16 of address */
4392                 bnx2x_cl45_write(bp, port,
4393                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4394                                ext_phy_addr,
4395                                MDIO_PCS_DEVAD,
4396                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4397                                (data_index>>16));
4398                 /* Bits 15-8 of address */
4399                 bnx2x_cl45_write(bp, port,
4400                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4401                                ext_phy_addr,
4402                                MDIO_PCS_DEVAD,
4403                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4404                                (data_index>>8));
4405
4406                 /* Bits 7-0 of address */
4407                 bnx2x_cl45_write(bp, port,
4408                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4409                                ext_phy_addr,
4410                                MDIO_PCS_DEVAD,
4411                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4412                                ((u16)data_index));
4413
4414                 byte_cnt = 0;
4415                 while (byte_cnt < 4 && data_index < size) {
4416                         bnx2x_cl45_write(bp, port,
4417                                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4418                                        ext_phy_addr,
4419                                MDIO_PCS_DEVAD,
4420                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4421                                data[data_index++]);
4422                         byte_cnt++;
4423                 }
4424
4425                 bnx2x_cl45_write(bp, port,
4426                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4427                                ext_phy_addr,
4428                                MDIO_PCS_DEVAD,
4429                                MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4430                                byte_cnt+4);
4431
4432                 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4433                 msleep(5); /* Wait 5 ms minimum between transs */
4434
4435                 /* Let the user know something's going on.*/
4436                 /* a pacifier ever 4K */
4437                 if ((data_index % 1023) == 0)
4438                         DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
4439         }
4440
4441         DP(NETIF_MSG_LINK, "\n");
4442         /* Transfer the last block if there is data remaining */
4443         if (last_trans_size) {
4444                 bnx2x_cl45_write(bp, port,
4445                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4446                         ext_phy_addr,
4447                         MDIO_PCS_DEVAD,
4448                         MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4449                         MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
4450
4451                 bnx2x_cl45_write(bp, port,
4452                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4453                                ext_phy_addr,
4454                                MDIO_PCS_DEVAD,
4455                                MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4456                                1);
4457
4458                 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4459
4460                 bnx2x_cl45_write(bp, port,
4461                              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4462                              ext_phy_addr,
4463                              MDIO_PCS_DEVAD,
4464                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4465                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
4466
4467                 /* Bits 23-16 of address */
4468                 bnx2x_cl45_write(bp, port,
4469                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4470                                ext_phy_addr,
4471                                MDIO_PCS_DEVAD,
4472                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4473                                (data_index>>16));
4474                 /* Bits 15-8 of address */
4475                 bnx2x_cl45_write(bp, port,
4476                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4477                                ext_phy_addr,
4478                                MDIO_PCS_DEVAD,
4479                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4480                                (data_index>>8));
4481
4482                 /* Bits 7-0 of address */
4483                 bnx2x_cl45_write(bp, port,
4484                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4485                                ext_phy_addr,
4486                                MDIO_PCS_DEVAD,
4487                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4488                                ((u16)data_index));
4489
4490                 byte_cnt = 0;
4491                 while (byte_cnt < last_trans_size && data_index < size) {
4492                         /* Bits 7-0 of address */
4493                         bnx2x_cl45_write(bp, port,
4494                                 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4495                                 ext_phy_addr,
4496                                 MDIO_PCS_DEVAD,
4497                                 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4498                                 data[data_index++]);
4499                         byte_cnt++;
4500                 }
4501
4502                 bnx2x_cl45_write(bp, port,
4503                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4504                                ext_phy_addr,
4505                                MDIO_PCS_DEVAD,
4506                                MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4507                                byte_cnt+4);
4508
4509                 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4510         }
4511
4512         /* DSP Remove Download Mode */
4513         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
4514                           MISC_REGISTERS_GPIO_LOW, port);
4515
4516         bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
4517
4518         /* wait 0.5 sec to allow it to run */
4519         for (cnt = 0; cnt < 100; cnt++)
4520                 msleep(5);
4521
4522         bnx2x_hw_reset(bp, port);
4523
4524         for (cnt = 0; cnt < 100; cnt++)
4525                 msleep(5);
4526
4527         /* Check that the code is started. In case the download
4528         checksum failed, the code won't be started. */
4529         bnx2x_cl45_read(bp, port,
4530                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4531                       ext_phy_addr,
4532                       MDIO_PCS_DEVAD,
4533                       MDIO_PCS_REG_7101_DSP_ACCESS,
4534                       &tmp);
4535
4536         code_started = (tmp & (1<<4));
4537         if (!code_started) {
4538                 DP(NETIF_MSG_LINK, "Download failed. Please check file.\n");
4539                 return -EINVAL;
4540         }
4541
4542         /* Verify that the file revision is now equal to the image
4543         revision within the DSP */
4544         bnx2x_cl45_read(bp, port,
4545                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4546                       ext_phy_addr,
4547                       MDIO_PMA_DEVAD,
4548                       MDIO_PMA_REG_7101_VER1,
4549                       &image_revision1);
4550
4551         bnx2x_cl45_read(bp, port,
4552                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4553                       ext_phy_addr,
4554                       MDIO_PMA_DEVAD,
4555                       MDIO_PMA_REG_7101_VER2,
4556                       &image_revision2);
4557
4558         if (data[0x14e] != (image_revision2&0xFF) ||
4559             data[0x14f] != ((image_revision2&0xFF00)>>8) ||
4560             data[0x150] != (image_revision1&0xFF) ||
4561             data[0x151] != ((image_revision1&0xFF00)>>8)) {
4562                 DP(NETIF_MSG_LINK, "Download failed.\n");
4563                 return -EINVAL;
4564         }
4565         DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
4566         return 0;
4567 }
4568
4569 u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
4570                       u8 driver_loaded, char data[], u32 size)
4571 {
4572         u8 rc = 0;
4573         u32 ext_phy_type;
4574         u8 ext_phy_addr;
4575         ext_phy_addr = ((ext_phy_config &
4576                         PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4577                         PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4578
4579         ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
4580
4581         switch (ext_phy_type) {
4582         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4583         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4584         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
4585         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
4586                 DP(NETIF_MSG_LINK,
4587                         "Flash download not supported for this ext phy\n");
4588                 rc = -EINVAL;
4589                 break;
4590         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4591                 /* Take ext phy out of reset */
4592                 if (!driver_loaded)
4593                         bnx2x_turn_on_ef(bp, port, ext_phy_addr, ext_phy_type);
4594                 rc = bnx2x_sfx7101_flash_download(bp, port, ext_phy_addr,
4595                                                 data, size);
4596                 if (!driver_loaded)
4597                         bnx2x_turn_off_sf(bp, port);
4598                 break;
4599         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4600         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
4601         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
4602         default:
4603                 DP(NETIF_MSG_LINK, "Invalid ext phy type\n");
4604                 rc = -EINVAL;
4605                 break;
4606         }
4607         return rc;
4608 }
4609