2ef7e81354e4c77adb27b55794e5a8f94afef72f
[akaros.git] / kern / drivers / net / bnx2x / bnx2x_link.c
1 /* Copyright 2008-2013 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 "akaros_compat.h"
18
19 #include "bnx2x.h"
20 #include "bnx2x_cmn.h"
21
22 typedef int (*read_sfp_module_eeprom_func_p)(struct bnx2x_phy *phy,
23                                              struct link_params *params,
24                                              uint8_t dev_addr, uint16_t addr,
25                                              uint8_t byte_cnt,
26                                              uint8_t *o_buf, uint8_t);
27 /********************************************************/
28 #define ETH_HLEN                        14
29 /* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */
30 #define ETH_OVREHEAD                    (ETHERHDRSIZE + 8 + 8)
31 #define ETH_MIN_PACKET_SIZE             60
32 #define ETH_MAX_PACKET_SIZE             1500
33 #define ETH_MAX_JUMBO_PACKET_SIZE       9600
34 #define MDIO_ACCESS_TIMEOUT             1000
35 #define WC_LANE_MAX                     4
36 #define I2C_SWITCH_WIDTH                2
37 #define I2C_BSC0                        0
38 #define I2C_BSC1                        1
39 #define I2C_WA_RETRY_CNT                3
40 #define I2C_WA_PWR_ITER                 (I2C_WA_RETRY_CNT - 1)
41 #define MCPR_IMC_COMMAND_READ_OP        1
42 #define MCPR_IMC_COMMAND_WRITE_OP       2
43
44 /* LED Blink rate that will achieve ~15.9Hz */
45 #define LED_BLINK_RATE_VAL_E3           354
46 #define LED_BLINK_RATE_VAL_E1X_E2       480
47 /***********************************************************/
48 /*                      Shortcut definitions               */
49 /***********************************************************/
50
51 #define NIG_LATCH_BC_ENABLE_MI_INT 0
52
53 #define NIG_STATUS_EMAC0_MI_INT \
54                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_MI_INT
55 #define NIG_STATUS_XGXS0_LINK10G \
56                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
57 #define NIG_STATUS_XGXS0_LINK_STATUS \
58                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
59 #define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
60                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
61 #define NIG_STATUS_SERDES0_LINK_STATUS \
62                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
63 #define NIG_MASK_MI_INT \
64                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
65 #define NIG_MASK_XGXS0_LINK10G \
66                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
67 #define NIG_MASK_XGXS0_LINK_STATUS \
68                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
69 #define NIG_MASK_SERDES0_LINK_STATUS \
70                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
71
72 #define MDIO_AN_CL73_OR_37_COMPLETE \
73                 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
74                  MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
75
76 #define XGXS_RESET_BITS \
77         (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW |   \
78          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ |      \
79          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN |    \
80          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
81          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
82
83 #define SERDES_RESET_BITS \
84         (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
85          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ |    \
86          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN |  \
87          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
88
89 #define AUTONEG_CL37            SHARED_HW_CFG_AN_ENABLE_CL37
90 #define AUTONEG_CL73            SHARED_HW_CFG_AN_ENABLE_CL73
91 #define AUTONEG_BAM             SHARED_HW_CFG_AN_ENABLE_BAM
92 #define AUTONEG_PARALLEL \
93                                 SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
94 #define AUTONEG_SGMII_FIBER_AUTODET \
95                                 SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
96 #define AUTONEG_REMOTE_PHY      SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
97
98 #define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
99                         MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
100 #define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
101                         MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
102 #define GP_STATUS_SPEED_MASK \
103                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
104 #define GP_STATUS_10M   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
105 #define GP_STATUS_100M  MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
106 #define GP_STATUS_1G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
107 #define GP_STATUS_2_5G  MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
108 #define GP_STATUS_5G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
109 #define GP_STATUS_6G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
110 #define GP_STATUS_10G_HIG \
111                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
112 #define GP_STATUS_10G_CX4 \
113                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
114 #define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
115 #define GP_STATUS_10G_KX4 \
116                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
117 #define GP_STATUS_10G_KR MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KR
118 #define GP_STATUS_10G_XFI   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_XFI
119 #define GP_STATUS_20G_DXGXS MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_DXGXS
120 #define GP_STATUS_10G_SFI   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_SFI
121 #define GP_STATUS_20G_KR2 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_KR2
122 #define LINK_10THD              LINK_STATUS_SPEED_AND_DUPLEX_10THD
123 #define LINK_10TFD              LINK_STATUS_SPEED_AND_DUPLEX_10TFD
124 #define LINK_100TXHD            LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
125 #define LINK_100T4              LINK_STATUS_SPEED_AND_DUPLEX_100T4
126 #define LINK_100TXFD            LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
127 #define LINK_1000THD            LINK_STATUS_SPEED_AND_DUPLEX_1000THD
128 #define LINK_1000TFD            LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
129 #define LINK_1000XFD            LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
130 #define LINK_2500THD            LINK_STATUS_SPEED_AND_DUPLEX_2500THD
131 #define LINK_2500TFD            LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
132 #define LINK_2500XFD            LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
133 #define LINK_10GTFD             LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
134 #define LINK_10GXFD             LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
135 #define LINK_20GTFD             LINK_STATUS_SPEED_AND_DUPLEX_20GTFD
136 #define LINK_20GXFD             LINK_STATUS_SPEED_AND_DUPLEX_20GXFD
137
138 #define LINK_UPDATE_MASK \
139                         (LINK_STATUS_SPEED_AND_DUPLEX_MASK | \
140                          LINK_STATUS_LINK_UP | \
141                          LINK_STATUS_PHYSICAL_LINK_FLAG | \
142                          LINK_STATUS_AUTO_NEGOTIATE_COMPLETE | \
143                          LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK | \
144                          LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK | \
145                          LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK | \
146                          LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE | \
147                          LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE)
148
149 #define SFP_EEPROM_CON_TYPE_ADDR                0x2
150         #define SFP_EEPROM_CON_TYPE_VAL_UNKNOWN 0x0
151         #define SFP_EEPROM_CON_TYPE_VAL_LC      0x7
152         #define SFP_EEPROM_CON_TYPE_VAL_COPPER  0x21
153         #define SFP_EEPROM_CON_TYPE_VAL_RJ45    0x22
154
155
156 #define SFP_EEPROM_10G_COMP_CODE_ADDR           0x3
157         #define SFP_EEPROM_10G_COMP_CODE_SR_MASK        (1<<4)
158         #define SFP_EEPROM_10G_COMP_CODE_LR_MASK        (1<<5)
159         #define SFP_EEPROM_10G_COMP_CODE_LRM_MASK       (1<<6)
160
161 #define SFP_EEPROM_1G_COMP_CODE_ADDR            0x6
162         #define SFP_EEPROM_1G_COMP_CODE_SX      (1<<0)
163         #define SFP_EEPROM_1G_COMP_CODE_LX      (1<<1)
164         #define SFP_EEPROM_1G_COMP_CODE_CX      (1<<2)
165         #define SFP_EEPROM_1G_COMP_CODE_BASE_T  (1<<3)
166
167 #define SFP_EEPROM_FC_TX_TECH_ADDR              0x8
168         #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
169         #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE  0x8
170
171 #define SFP_EEPROM_OPTIONS_ADDR                 0x40
172         #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
173 #define SFP_EEPROM_OPTIONS_SIZE                 2
174
175 #define EDC_MODE_LINEAR                         0x0022
176 #define EDC_MODE_LIMITING                               0x0044
177 #define EDC_MODE_PASSIVE_DAC                    0x0055
178 #define EDC_MODE_ACTIVE_DAC                     0x0066
179
180 /* ETS defines*/
181 #define DCBX_INVALID_COS                                        (0xFF)
182
183 #define ETS_BW_LIMIT_CREDIT_UPPER_BOUND         (0x5000)
184 #define ETS_BW_LIMIT_CREDIT_WEIGHT              (0x5000)
185 #define ETS_E3B0_NIG_MIN_W_VAL_UP_TO_10GBPS             (1360)
186 #define ETS_E3B0_NIG_MIN_W_VAL_20GBPS                   (2720)
187 #define ETS_E3B0_PBF_MIN_W_VAL                          (10000)
188
189 #define MAX_PACKET_SIZE                                 (9700)
190 #define MAX_KR_LINK_RETRY                               4
191
192 /**********************************************************/
193 /*                     INTERFACE                          */
194 /**********************************************************/
195
196 #define CL22_WR_OVER_CL45(_bp, _phy, _bank, _addr, _val) \
197         bnx2x_cl45_write(_bp, _phy, \
198                 (_phy)->def_md_devad, \
199                 (_bank + (_addr & 0xf)), \
200                 _val)
201
202 #define CL22_RD_OVER_CL45(_bp, _phy, _bank, _addr, _val) \
203         bnx2x_cl45_read(_bp, _phy, \
204                 (_phy)->def_md_devad, \
205                 (_bank + (_addr & 0xf)), \
206                 _val)
207
208 static int bnx2x_check_half_open_conn(struct link_params *params,
209                                       struct link_vars *vars, uint8_t notify);
210 static int bnx2x_sfp_module_detection(struct bnx2x_phy *phy,
211                                       struct link_params *params);
212
213 static uint32_t bnx2x_bits_en(struct bnx2x *bp, uint32_t reg, uint32_t bits)
214 {
215         uint32_t val = REG_RD(bp, reg);
216
217         val |= bits;
218         REG_WR(bp, reg, val);
219         return val;
220 }
221
222 static uint32_t bnx2x_bits_dis(struct bnx2x *bp, uint32_t reg, uint32_t bits)
223 {
224         uint32_t val = REG_RD(bp, reg);
225
226         val &= ~bits;
227         REG_WR(bp, reg, val);
228         return val;
229 }
230
231 /*
232  * bnx2x_check_lfa - This function checks if link reinitialization is required,
233  *                   or link flap can be avoided.
234  *
235  * @params:     link parameters
236  * Returns 0 if Link Flap Avoidance conditions are met otherwise, the failed
237  *         condition code.
238  */
239 static int bnx2x_check_lfa(struct link_params *params)
240 {
241         uint32_t link_status, cfg_idx, lfa_mask, cfg_size;
242         uint32_t cur_speed_cap_mask, cur_req_fc_auto_adv, additional_config;
243         uint32_t saved_val, req_val, eee_status;
244         struct bnx2x *bp = params->bp;
245
246         additional_config =
247                 REG_RD(bp, params->lfa_base +
248                            offsetof(struct shmem_lfa, additional_config));
249
250         /* NOTE: must be first condition checked -
251         * to verify DCC bit is cleared in any case!
252         */
253         if (additional_config & NO_LFA_DUE_TO_DCC_MASK) {
254                 DP(NETIF_MSG_LINK, "No LFA due to DCC flap after clp exit\n");
255                 REG_WR(bp, params->lfa_base +
256                            offsetof(struct shmem_lfa, additional_config),
257                        additional_config & ~NO_LFA_DUE_TO_DCC_MASK);
258                 return LFA_DCC_LFA_DISABLED;
259         }
260
261         /* Verify that link is up */
262         link_status = REG_RD(bp, params->shmem_base +
263                              offsetof(struct shmem_region,
264                                       port_mb[params->port].link_status));
265         if (!(link_status & LINK_STATUS_LINK_UP))
266                 return LFA_LINK_DOWN;
267
268         /* if loaded after BOOT from SAN, don't flap the link in any case and
269          * rely on link set by preboot driver
270          */
271         if (params->feature_config_flags & FEATURE_CONFIG_BOOT_FROM_SAN)
272                 return 0;
273
274         /* Verify that loopback mode is not set */
275         if (params->loopback_mode)
276                 return LFA_LOOPBACK_ENABLED;
277
278         /* Verify that MFW supports LFA */
279         if (!params->lfa_base)
280                 return LFA_MFW_IS_TOO_OLD;
281
282         if (params->num_phys == 3) {
283                 cfg_size = 2;
284                 lfa_mask = 0xffffffff;
285         } else {
286                 cfg_size = 1;
287                 lfa_mask = 0xffff;
288         }
289
290         /* Compare Duplex */
291         saved_val = REG_RD(bp, params->lfa_base +
292                            offsetof(struct shmem_lfa, req_duplex));
293         req_val = params->req_duplex[0] | (params->req_duplex[1] << 16);
294         if ((saved_val & lfa_mask) != (req_val & lfa_mask)) {
295                 DP(NETIF_MSG_LINK, "Duplex mismatch %x vs. %x\n",
296                                (saved_val & lfa_mask), (req_val & lfa_mask));
297                 return LFA_DUPLEX_MISMATCH;
298         }
299         /* Compare Flow Control */
300         saved_val = REG_RD(bp, params->lfa_base +
301                            offsetof(struct shmem_lfa, req_flow_ctrl));
302         req_val = params->req_flow_ctrl[0] | (params->req_flow_ctrl[1] << 16);
303         if ((saved_val & lfa_mask) != (req_val & lfa_mask)) {
304                 DP(NETIF_MSG_LINK, "Flow control mismatch %x vs. %x\n",
305                                (saved_val & lfa_mask), (req_val & lfa_mask));
306                 return LFA_FLOW_CTRL_MISMATCH;
307         }
308         /* Compare Link Speed */
309         saved_val = REG_RD(bp, params->lfa_base +
310                            offsetof(struct shmem_lfa, req_line_speed));
311         req_val = params->req_line_speed[0] | (params->req_line_speed[1] << 16);
312         if ((saved_val & lfa_mask) != (req_val & lfa_mask)) {
313                 DP(NETIF_MSG_LINK, "Link speed mismatch %x vs. %x\n",
314                                (saved_val & lfa_mask), (req_val & lfa_mask));
315                 return LFA_LINK_SPEED_MISMATCH;
316         }
317
318         for (cfg_idx = 0; cfg_idx < cfg_size; cfg_idx++) {
319                 cur_speed_cap_mask = REG_RD(bp, params->lfa_base +
320                                             offsetof(struct shmem_lfa,
321                                                      speed_cap_mask[cfg_idx]));
322
323                 if (cur_speed_cap_mask != params->speed_cap_mask[cfg_idx]) {
324                         DP(NETIF_MSG_LINK, "Speed Cap mismatch %x vs. %x\n",
325                                        cur_speed_cap_mask,
326                                        params->speed_cap_mask[cfg_idx]);
327                         return LFA_SPEED_CAP_MISMATCH;
328                 }
329         }
330
331         cur_req_fc_auto_adv =
332                 REG_RD(bp, params->lfa_base +
333                        offsetof(struct shmem_lfa, additional_config)) &
334                 REQ_FC_AUTO_ADV_MASK;
335
336         if ((uint16_t)cur_req_fc_auto_adv != params->req_fc_auto_adv) {
337                 DP(NETIF_MSG_LINK, "Flow Ctrl AN mismatch %x vs. %x\n",
338                                cur_req_fc_auto_adv, params->req_fc_auto_adv);
339                 return LFA_FLOW_CTRL_MISMATCH;
340         }
341
342         eee_status = REG_RD(bp, params->shmem2_base +
343                             offsetof(struct shmem2_region,
344                                      eee_status[params->port]));
345
346         if (((eee_status & SHMEM_EEE_LPI_REQUESTED_BIT) ^
347              (params->eee_mode & EEE_MODE_ENABLE_LPI)) ||
348             ((eee_status & SHMEM_EEE_REQUESTED_BIT) ^
349              (params->eee_mode & EEE_MODE_ADV_LPI))) {
350                 DP(NETIF_MSG_LINK, "EEE mismatch %x vs. %x\n", params->eee_mode,
351                                eee_status);
352                 return LFA_EEE_MISMATCH;
353         }
354
355         /* LFA conditions are met */
356         return 0;
357 }
358 /******************************************************************/
359 /*                      EPIO/GPIO section                         */
360 /******************************************************************/
361 static void bnx2x_get_epio(struct bnx2x *bp, uint32_t epio_pin, uint32_t *en)
362 {
363         uint32_t epio_mask, gp_oenable;
364         *en = 0;
365         /* Sanity check */
366         if (epio_pin > 31) {
367                 DP(NETIF_MSG_LINK, "Invalid EPIO pin %d to get\n", epio_pin);
368                 return;
369         }
370
371         epio_mask = 1 << epio_pin;
372         /* Set this EPIO to output */
373         gp_oenable = REG_RD(bp, MCP_REG_MCPR_GP_OENABLE);
374         REG_WR(bp, MCP_REG_MCPR_GP_OENABLE, gp_oenable & ~epio_mask);
375
376         *en = (REG_RD(bp, MCP_REG_MCPR_GP_INPUTS) & epio_mask) >> epio_pin;
377 }
378 static void bnx2x_set_epio(struct bnx2x *bp, uint32_t epio_pin, uint32_t en)
379 {
380         uint32_t epio_mask, gp_output, gp_oenable;
381
382         /* Sanity check */
383         if (epio_pin > 31) {
384                 DP(NETIF_MSG_LINK, "Invalid EPIO pin %d to set\n", epio_pin);
385                 return;
386         }
387         DP(NETIF_MSG_LINK, "Setting EPIO pin %d to %d\n", epio_pin, en);
388         epio_mask = 1 << epio_pin;
389         /* Set this EPIO to output */
390         gp_output = REG_RD(bp, MCP_REG_MCPR_GP_OUTPUTS);
391         if (en)
392                 gp_output |= epio_mask;
393         else
394                 gp_output &= ~epio_mask;
395
396         REG_WR(bp, MCP_REG_MCPR_GP_OUTPUTS, gp_output);
397
398         /* Set the value for this EPIO */
399         gp_oenable = REG_RD(bp, MCP_REG_MCPR_GP_OENABLE);
400         REG_WR(bp, MCP_REG_MCPR_GP_OENABLE, gp_oenable | epio_mask);
401 }
402
403 static void bnx2x_set_cfg_pin(struct bnx2x *bp, uint32_t pin_cfg,
404                               uint32_t val)
405 {
406         if (pin_cfg == PIN_CFG_NA)
407                 return;
408         if (pin_cfg >= PIN_CFG_EPIO0) {
409                 bnx2x_set_epio(bp, pin_cfg - PIN_CFG_EPIO0, val);
410         } else {
411                 uint8_t gpio_num = (pin_cfg - PIN_CFG_GPIO0_P0) & 0x3;
412                 uint8_t gpio_port = (pin_cfg - PIN_CFG_GPIO0_P0) >> 2;
413                 bnx2x_set_gpio(bp, gpio_num, (uint8_t)val, gpio_port);
414         }
415 }
416
417 static uint32_t bnx2x_get_cfg_pin(struct bnx2x *bp, uint32_t pin_cfg,
418                                   uint32_t *val)
419 {
420         if (pin_cfg == PIN_CFG_NA)
421                 return -EINVAL;
422         if (pin_cfg >= PIN_CFG_EPIO0) {
423                 bnx2x_get_epio(bp, pin_cfg - PIN_CFG_EPIO0, val);
424         } else {
425                 uint8_t gpio_num = (pin_cfg - PIN_CFG_GPIO0_P0) & 0x3;
426                 uint8_t gpio_port = (pin_cfg - PIN_CFG_GPIO0_P0) >> 2;
427                 *val = bnx2x_get_gpio(bp, gpio_num, gpio_port);
428         }
429         return 0;
430
431 }
432 /******************************************************************/
433 /*                              ETS section                       */
434 /******************************************************************/
435 static void bnx2x_ets_e2e3a0_disabled(struct link_params *params)
436 {
437         /* ETS disabled configuration*/
438         struct bnx2x *bp = params->bp;
439
440         DP(NETIF_MSG_LINK, "ETS E2E3 disabled configuration\n");
441
442         /* mapping between entry  priority to client number (0,1,2 -debug and
443          * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
444          * 3bits client num.
445          *   PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
446          * cos1-100     cos0-011     dbg1-010     dbg0-001     MCP-000
447          */
448
449         REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, 0x4688);
450         /* Bitmap of 5bits length. Each bit specifies whether the entry behaves
451          * as strict.  Bits 0,1,2 - debug and management entries, 3 -
452          * COS0 entry, 4 - COS1 entry.
453          * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
454          * bit4   bit3    bit2   bit1     bit0
455          * MCP and debug are strict
456          */
457
458         REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
459         /* defines which entries (clients) are subjected to WFQ arbitration */
460         REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0);
461         /* For strict priority entries defines the number of consecutive
462          * slots for the highest priority.
463          */
464         REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
465         /* mapping between the CREDIT_WEIGHT registers and actual client
466          * numbers
467          */
468         REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0);
469         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0);
470         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0);
471
472         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, 0);
473         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, 0);
474         REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, 0);
475         /* ETS mode disable */
476         REG_WR(bp, PBF_REG_ETS_ENABLED, 0);
477         /* If ETS mode is enabled (there is no strict priority) defines a WFQ
478          * weight for COS0/COS1.
479          */
480         REG_WR(bp, PBF_REG_COS0_WEIGHT, 0x2710);
481         REG_WR(bp, PBF_REG_COS1_WEIGHT, 0x2710);
482         /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter */
483         REG_WR(bp, PBF_REG_COS0_UPPER_BOUND, 0x989680);
484         REG_WR(bp, PBF_REG_COS1_UPPER_BOUND, 0x989680);
485         /* Defines the number of consecutive slots for the strict priority */
486         REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
487 }
488 /******************************************************************************
489 * Description:
490 *       Getting min_w_val will be set according to line speed .
491 *.
492 ******************************************************************************/
493 static uint32_t bnx2x_ets_get_min_w_val_nig(const struct link_vars *vars)
494 {
495         uint32_t min_w_val = 0;
496         /* Calculate min_w_val.*/
497         if (vars->link_up) {
498                 if (vars->line_speed == SPEED_20000)
499                         min_w_val = ETS_E3B0_NIG_MIN_W_VAL_20GBPS;
500                 else
501                         min_w_val = ETS_E3B0_NIG_MIN_W_VAL_UP_TO_10GBPS;
502         } else
503                 min_w_val = ETS_E3B0_NIG_MIN_W_VAL_20GBPS;
504         /* If the link isn't up (static configuration for example ) The
505          * link will be according to 20GBPS.
506          */
507         return min_w_val;
508 }
509 /******************************************************************************
510 * Description:
511 *       Getting credit upper bound form min_w_val.
512 *.
513 ******************************************************************************/
514 static uint32_t bnx2x_ets_get_credit_upper_bound(const uint32_t min_w_val)
515 {
516         const uint32_t credit_upper_bound = (uint32_t)MAXVAL((150 * min_w_val),
517                                                 MAX_PACKET_SIZE);
518         return credit_upper_bound;
519 }
520 /******************************************************************************
521 * Description:
522 *       Set credit upper bound for NIG.
523 *.
524 ******************************************************************************/
525 static void bnx2x_ets_e3b0_set_credit_upper_bound_nig(
526         const struct link_params *params,
527         const uint32_t min_w_val)
528 {
529         struct bnx2x *bp = params->bp;
530         const uint8_t port = params->port;
531         const uint32_t credit_upper_bound =
532             bnx2x_ets_get_credit_upper_bound(min_w_val);
533
534         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_0 :
535                 NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, credit_upper_bound);
536         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_1 :
537                    NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, credit_upper_bound);
538         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_2 :
539                    NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_2, credit_upper_bound);
540         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_3 :
541                    NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_3, credit_upper_bound);
542         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_4 :
543                    NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_4, credit_upper_bound);
544         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_5 :
545                    NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_5, credit_upper_bound);
546
547         if (!port) {
548                 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_6,
549                         credit_upper_bound);
550                 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_7,
551                         credit_upper_bound);
552                 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_8,
553                         credit_upper_bound);
554         }
555 }
556 /******************************************************************************
557 * Description:
558 *       Will return the NIG ETS registers to init values.Except
559 *       credit_upper_bound.
560 *       That isn't used in this configuration (No WFQ is enabled) and will be
561 *       configured acording to spec
562 *.
563 ******************************************************************************/
564 static void bnx2x_ets_e3b0_nig_disabled(const struct link_params *params,
565                                         const struct link_vars *vars)
566 {
567         struct bnx2x *bp = params->bp;
568         const uint8_t port = params->port;
569         const uint32_t min_w_val = bnx2x_ets_get_min_w_val_nig(vars);
570         /* Mapping between entry  priority to client number (0,1,2 -debug and
571          * management clients, 3 - COS0 client, 4 - COS1, ... 8 -
572          * COS5)(HIGHEST) 4bits client num.TODO_ETS - Should be done by
573          * reset value or init tool
574          */
575         if (port) {
576                 REG_WR(bp, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_LSB, 0x543210);
577                 REG_WR(bp, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_MSB, 0x0);
578         } else {
579                 REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_LSB, 0x76543210);
580                 REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_MSB, 0x8);
581         }
582         /* For strict priority entries defines the number of consecutive
583          * slots for the highest priority.
584          */
585         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS :
586                    NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
587         /* Mapping between the CREDIT_WEIGHT registers and actual client
588          * numbers
589          */
590         if (port) {
591                 /*Port 1 has 6 COS*/
592                 REG_WR(bp, NIG_REG_P1_TX_ARB_CLIENT_CREDIT_MAP2_LSB, 0x210543);
593                 REG_WR(bp, NIG_REG_P1_TX_ARB_CLIENT_CREDIT_MAP2_MSB, 0x0);
594         } else {
595                 /*Port 0 has 9 COS*/
596                 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP2_LSB,
597                        0x43210876);
598                 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP2_MSB, 0x5);
599         }
600
601         /* Bitmap of 5bits length. Each bit specifies whether the entry behaves
602          * as strict.  Bits 0,1,2 - debug and management entries, 3 -
603          * COS0 entry, 4 - COS1 entry.
604          * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
605          * bit4   bit3    bit2   bit1     bit0
606          * MCP and debug are strict
607          */
608         if (port)
609                 REG_WR(bp, NIG_REG_P1_TX_ARB_CLIENT_IS_STRICT, 0x3f);
610         else
611                 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1ff);
612         /* defines which entries (clients) are subjected to WFQ arbitration */
613         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_SUBJECT2WFQ :
614                    NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0);
615
616         /* Please notice the register address are note continuous and a
617          * for here is note appropriate.In 2 port mode port0 only COS0-5
618          * can be used. DEBUG1,DEBUG1,MGMT are never used for WFQ* In 4
619          * port mode port1 only COS0-2 can be used. DEBUG1,DEBUG1,MGMT
620          * are never used for WFQ
621          */
622         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_0 :
623                    NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0x0);
624         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_1 :
625                    NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0x0);
626         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_2 :
627                    NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_2, 0x0);
628         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_3 :
629                    NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_3, 0x0);
630         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_4 :
631                    NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_4, 0x0);
632         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_5 :
633                    NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_5, 0x0);
634         if (!port) {
635                 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_6, 0x0);
636                 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_7, 0x0);
637                 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_8, 0x0);
638         }
639
640         bnx2x_ets_e3b0_set_credit_upper_bound_nig(params, min_w_val);
641 }
642 /******************************************************************************
643 * Description:
644 *       Set credit upper bound for PBF.
645 *.
646 ******************************************************************************/
647 static void bnx2x_ets_e3b0_set_credit_upper_bound_pbf(
648         const struct link_params *params,
649         const uint32_t min_w_val)
650 {
651         struct bnx2x *bp = params->bp;
652         const uint32_t credit_upper_bound =
653             bnx2x_ets_get_credit_upper_bound(min_w_val);
654         const uint8_t port = params->port;
655         uint32_t base_upper_bound = 0;
656         uint8_t max_cos = 0;
657         uint8_t i = 0;
658         /* In 2 port mode port0 has COS0-5 that can be used for WFQ.In 4
659          * port mode port1 has COS0-2 that can be used for WFQ.
660          */
661         if (!port) {
662                 base_upper_bound = PBF_REG_COS0_UPPER_BOUND_P0;
663                 max_cos = DCBX_E3B0_MAX_NUM_COS_PORT0;
664         } else {
665                 base_upper_bound = PBF_REG_COS0_UPPER_BOUND_P1;
666                 max_cos = DCBX_E3B0_MAX_NUM_COS_PORT1;
667         }
668
669         for (i = 0; i < max_cos; i++)
670                 REG_WR(bp, base_upper_bound + (i << 2), credit_upper_bound);
671 }
672
673 /******************************************************************************
674 * Description:
675 *       Will return the PBF ETS registers to init values.Except
676 *       credit_upper_bound.
677 *       That isn't used in this configuration (No WFQ is enabled) and will be
678 *       configured acording to spec
679 *.
680 ******************************************************************************/
681 static void bnx2x_ets_e3b0_pbf_disabled(const struct link_params *params)
682 {
683         struct bnx2x *bp = params->bp;
684         const uint8_t port = params->port;
685         const uint32_t min_w_val_pbf = ETS_E3B0_PBF_MIN_W_VAL;
686         uint8_t i = 0;
687         uint32_t base_weight = 0;
688         uint8_t max_cos = 0;
689
690         /* Mapping between entry  priority to client number 0 - COS0
691          * client, 2 - COS1, ... 5 - COS5)(HIGHEST) 4bits client num.
692          * TODO_ETS - Should be done by reset value or init tool
693          */
694         if (port)
695                 /*  0x688 (|011|0 10|00 1|000) */
696                 REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P1 , 0x688);
697         else
698                 /*  (10 1|100 |011|0 10|00 1|000) */
699                 REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P0 , 0x2C688);
700
701         /* TODO_ETS - Should be done by reset value or init tool */
702         if (port)
703                 /* 0x688 (|011|0 10|00 1|000)*/
704                 REG_WR(bp, PBF_REG_ETS_ARB_CLIENT_CREDIT_MAP_P1, 0x688);
705         else
706         /* 0x2C688 (10 1|100 |011|0 10|00 1|000) */
707         REG_WR(bp, PBF_REG_ETS_ARB_CLIENT_CREDIT_MAP_P0, 0x2C688);
708
709         REG_WR(bp, (port) ? PBF_REG_ETS_ARB_NUM_STRICT_ARB_SLOTS_P1 :
710                    PBF_REG_ETS_ARB_NUM_STRICT_ARB_SLOTS_P0 , 0x100);
711
712
713         REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P1 :
714                    PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P0 , 0);
715
716         REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P1 :
717                    PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P0 , 0);
718         /* In 2 port mode port0 has COS0-5 that can be used for WFQ.
719          * In 4 port mode port1 has COS0-2 that can be used for WFQ.
720          */
721         if (!port) {
722                 base_weight = PBF_REG_COS0_WEIGHT_P0;
723                 max_cos = DCBX_E3B0_MAX_NUM_COS_PORT0;
724         } else {
725                 base_weight = PBF_REG_COS0_WEIGHT_P1;
726                 max_cos = DCBX_E3B0_MAX_NUM_COS_PORT1;
727         }
728
729         for (i = 0; i < max_cos; i++)
730                 REG_WR(bp, base_weight + (0x4 * i), 0);
731
732         bnx2x_ets_e3b0_set_credit_upper_bound_pbf(params, min_w_val_pbf);
733 }
734 /******************************************************************************
735 * Description:
736 *       E3B0 disable will return basicly the values to init values.
737 *.
738 ******************************************************************************/
739 static int bnx2x_ets_e3b0_disabled(const struct link_params *params,
740                                    const struct link_vars *vars)
741 {
742         struct bnx2x *bp = params->bp;
743
744         if (!CHIP_IS_E3B0(bp)) {
745                 DP(NETIF_MSG_LINK,
746                    "bnx2x_ets_e3b0_disabled the chip isn't E3B0\n");
747                 return -EINVAL;
748         }
749
750         bnx2x_ets_e3b0_nig_disabled(params, vars);
751
752         bnx2x_ets_e3b0_pbf_disabled(params);
753
754         return 0;
755 }
756
757 /******************************************************************************
758 * Description:
759 *       Disable will return basicly the values to init values.
760 *
761 ******************************************************************************/
762 int bnx2x_ets_disabled(struct link_params *params,
763                       struct link_vars *vars)
764 {
765         struct bnx2x *bp = params->bp;
766         int bnx2x_status = 0;
767
768         if ((CHIP_IS_E2(bp)) || (CHIP_IS_E3A0(bp)))
769                 bnx2x_ets_e2e3a0_disabled(params);
770         else if (CHIP_IS_E3B0(bp))
771                 bnx2x_status = bnx2x_ets_e3b0_disabled(params, vars);
772         else {
773                 DP(NETIF_MSG_LINK, "bnx2x_ets_disabled - chip not supported\n");
774                 return -EINVAL;
775         }
776
777         return bnx2x_status;
778 }
779
780 /******************************************************************************
781 * Description
782 *       Set the COS mappimg to SP and BW until this point all the COS are not
783 *       set as SP or BW.
784 ******************************************************************************/
785 static int bnx2x_ets_e3b0_cli_map(const struct link_params *params,
786                                   const struct bnx2x_ets_params *ets_params,
787                                   const uint8_t cos_sp_bitmap,
788                                   const uint8_t cos_bw_bitmap)
789 {
790         struct bnx2x *bp = params->bp;
791         const uint8_t port = params->port;
792         const uint8_t nig_cli_sp_bitmap = 0x7 | (cos_sp_bitmap << 3);
793         const uint8_t pbf_cli_sp_bitmap = cos_sp_bitmap;
794         const uint8_t nig_cli_subject2wfq_bitmap = cos_bw_bitmap << 3;
795         const uint8_t pbf_cli_subject2wfq_bitmap = cos_bw_bitmap;
796
797         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_STRICT :
798                NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, nig_cli_sp_bitmap);
799
800         REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P1 :
801                PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P0 , pbf_cli_sp_bitmap);
802
803         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_SUBJECT2WFQ :
804                NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ,
805                nig_cli_subject2wfq_bitmap);
806
807         REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P1 :
808                PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P0,
809                pbf_cli_subject2wfq_bitmap);
810
811         return 0;
812 }
813
814 /******************************************************************************
815 * Description:
816 *       This function is needed because NIG ARB_CREDIT_WEIGHT_X are
817 *       not continues and ARB_CREDIT_WEIGHT_0 + offset is suitable.
818 ******************************************************************************/
819 static int bnx2x_ets_e3b0_set_cos_bw(struct bnx2x *bp,
820                                      const uint8_t cos_entry,
821                                      const uint32_t min_w_val_nig,
822                                      const uint32_t min_w_val_pbf,
823                                      const uint16_t total_bw,
824                                      const uint8_t bw,
825                                      const uint8_t port)
826 {
827         uint32_t nig_reg_adress_crd_weight = 0;
828         uint32_t pbf_reg_adress_crd_weight = 0;
829         /* Calculate and set BW for this COS - use 1 instead of 0 for BW */
830         const uint32_t cos_bw_nig = ((bw ? bw : 1) * min_w_val_nig) / total_bw;
831         const uint32_t cos_bw_pbf = ((bw ? bw : 1) * min_w_val_pbf) / total_bw;
832
833         switch (cos_entry) {
834         case 0:
835             nig_reg_adress_crd_weight =
836                  (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_0 :
837                      NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0;
838              pbf_reg_adress_crd_weight = (port) ?
839                  PBF_REG_COS0_WEIGHT_P1 : PBF_REG_COS0_WEIGHT_P0;
840              break;
841         case 1:
842              nig_reg_adress_crd_weight = (port) ?
843                  NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_1 :
844                  NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1;
845              pbf_reg_adress_crd_weight = (port) ?
846                  PBF_REG_COS1_WEIGHT_P1 : PBF_REG_COS1_WEIGHT_P0;
847              break;
848         case 2:
849              nig_reg_adress_crd_weight = (port) ?
850                  NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_2 :
851                  NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_2;
852
853                  pbf_reg_adress_crd_weight = (port) ?
854                      PBF_REG_COS2_WEIGHT_P1 : PBF_REG_COS2_WEIGHT_P0;
855              break;
856         case 3:
857             if (port)
858                         return -EINVAL;
859              nig_reg_adress_crd_weight =
860                  NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_3;
861              pbf_reg_adress_crd_weight =
862                  PBF_REG_COS3_WEIGHT_P0;
863              break;
864         case 4:
865             if (port)
866                 return -EINVAL;
867              nig_reg_adress_crd_weight =
868                  NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_4;
869              pbf_reg_adress_crd_weight = PBF_REG_COS4_WEIGHT_P0;
870              break;
871         case 5:
872             if (port)
873                 return -EINVAL;
874              nig_reg_adress_crd_weight =
875                  NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_5;
876              pbf_reg_adress_crd_weight = PBF_REG_COS5_WEIGHT_P0;
877              break;
878         }
879
880         REG_WR(bp, nig_reg_adress_crd_weight, cos_bw_nig);
881
882         REG_WR(bp, pbf_reg_adress_crd_weight, cos_bw_pbf);
883
884         return 0;
885 }
886 /******************************************************************************
887 * Description:
888 *       Calculate the total BW.A value of 0 isn't legal.
889 *
890 ******************************************************************************/
891 static int bnx2x_ets_e3b0_get_total_bw(
892         const struct link_params *params,
893         struct bnx2x_ets_params *ets_params,
894         uint16_t *total_bw)
895 {
896         struct bnx2x *bp = params->bp;
897         uint8_t cos_idx = 0;
898         uint8_t is_bw_cos_exist = 0;
899
900         *total_bw = 0 ;
901         /* Calculate total BW requested */
902         for (cos_idx = 0; cos_idx < ets_params->num_of_cos; cos_idx++) {
903                 if (ets_params->cos[cos_idx].state == bnx2x_cos_state_bw) {
904                         is_bw_cos_exist = 1;
905                         if (!ets_params->cos[cos_idx].params.bw_params.bw) {
906                                 DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config BW"
907                                                    "was set to 0\n");
908                                 /* This is to prevent a state when ramrods
909                                  * can't be sent
910                                  */
911                                 ets_params->cos[cos_idx].params.bw_params.bw
912                                          = 1;
913                         }
914                         *total_bw +=
915                                 ets_params->cos[cos_idx].params.bw_params.bw;
916                 }
917         }
918
919         /* Check total BW is valid */
920         if ((is_bw_cos_exist == 1) && (*total_bw != 100)) {
921                 if (*total_bw == 0) {
922                         DP(NETIF_MSG_LINK,
923                            "bnx2x_ets_E3B0_config total BW shouldn't be 0\n");
924                         return -EINVAL;
925                 }
926                 DP(NETIF_MSG_LINK,
927                    "bnx2x_ets_E3B0_config total BW should be 100\n");
928                 /* We can handle a case whre the BW isn't 100 this can happen
929                  * if the TC are joined.
930                  */
931         }
932         return 0;
933 }
934
935 /******************************************************************************
936 * Description:
937 *       Invalidate all the sp_pri_to_cos.
938 *
939 ******************************************************************************/
940 static void bnx2x_ets_e3b0_sp_pri_to_cos_init(uint8_t *sp_pri_to_cos)
941 {
942         uint8_t pri = 0;
943         for (pri = 0; pri < DCBX_MAX_NUM_COS; pri++)
944                 sp_pri_to_cos[pri] = DCBX_INVALID_COS;
945 }
946 /******************************************************************************
947 * Description:
948 *       Calculate and set the SP (ARB_PRIORITY_CLIENT) NIG and PBF registers
949 *       according to sp_pri_to_cos.
950 *
951 ******************************************************************************/
952 static int bnx2x_ets_e3b0_sp_pri_to_cos_set(const struct link_params *params,
953                                             uint8_t *sp_pri_to_cos,
954                                             const uint8_t pri,
955                                             const uint8_t cos_entry)
956 {
957         struct bnx2x *bp = params->bp;
958         const uint8_t port = params->port;
959         const uint8_t max_num_of_cos = (port) ? DCBX_E3B0_MAX_NUM_COS_PORT1 :
960                 DCBX_E3B0_MAX_NUM_COS_PORT0;
961
962         if (pri >= max_num_of_cos) {
963                 DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid "
964                    "parameter Illegal strict priority\n");
965             return -EINVAL;
966         }
967
968         if (sp_pri_to_cos[pri] != DCBX_INVALID_COS) {
969                 DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid "
970                                    "parameter There can't be two COS's with "
971                                    "the same strict pri\n");
972                 return -EINVAL;
973         }
974
975         sp_pri_to_cos[pri] = cos_entry;
976         return 0;
977
978 }
979
980 /******************************************************************************
981 * Description:
982 *       Returns the correct value according to COS and priority in
983 *       the sp_pri_cli register.
984 *
985 ******************************************************************************/
986 static uint64_t bnx2x_e3b0_sp_get_pri_cli_reg(const uint8_t cos,
987                                          const uint8_t cos_offset,
988                                          const uint8_t pri_set,
989                                          const uint8_t pri_offset,
990                                          const uint8_t entry_size)
991 {
992         uint64_t pri_cli_nig = 0;
993         pri_cli_nig = ((uint64_t)(cos + cos_offset)) << (entry_size *
994                                                     (pri_set + pri_offset));
995
996         return pri_cli_nig;
997 }
998 /******************************************************************************
999 * Description:
1000 *       Returns the correct value according to COS and priority in the
1001 *       sp_pri_cli register for NIG.
1002 *
1003 ******************************************************************************/
1004 static uint64_t bnx2x_e3b0_sp_get_pri_cli_reg_nig(const uint8_t cos,
1005                                              const uint8_t pri_set)
1006 {
1007         /* MCP Dbg0 and dbg1 are always with higher strict pri*/
1008         const uint8_t nig_cos_offset = 3;
1009         const uint8_t nig_pri_offset = 3;
1010
1011         return bnx2x_e3b0_sp_get_pri_cli_reg(cos, nig_cos_offset, pri_set,
1012                 nig_pri_offset, 4);
1013
1014 }
1015 /******************************************************************************
1016 * Description:
1017 *       Returns the correct value according to COS and priority in the
1018 *       sp_pri_cli register for PBF.
1019 *
1020 ******************************************************************************/
1021 static uint64_t bnx2x_e3b0_sp_get_pri_cli_reg_pbf(const uint8_t cos,
1022                                              const uint8_t pri_set)
1023 {
1024         const uint8_t pbf_cos_offset = 0;
1025         const uint8_t pbf_pri_offset = 0;
1026
1027         return bnx2x_e3b0_sp_get_pri_cli_reg(cos, pbf_cos_offset, pri_set,
1028                 pbf_pri_offset, 3);
1029
1030 }
1031
1032 /******************************************************************************
1033 * Description:
1034 *       Calculate and set the SP (ARB_PRIORITY_CLIENT) NIG and PBF registers
1035 *       according to sp_pri_to_cos.(which COS has higher priority)
1036 *
1037 ******************************************************************************/
1038 static int bnx2x_ets_e3b0_sp_set_pri_cli_reg(const struct link_params *params,
1039                                              uint8_t *sp_pri_to_cos)
1040 {
1041         struct bnx2x *bp = params->bp;
1042         uint8_t i = 0;
1043         const uint8_t port = params->port;
1044         /* MCP Dbg0 and dbg1 are always with higher strict pri*/
1045         uint64_t pri_cli_nig = 0x210;
1046         uint32_t pri_cli_pbf = 0x0;
1047         uint8_t pri_set = 0;
1048         uint8_t pri_bitmask = 0;
1049         const uint8_t max_num_of_cos = (port) ? DCBX_E3B0_MAX_NUM_COS_PORT1 :
1050                 DCBX_E3B0_MAX_NUM_COS_PORT0;
1051
1052         uint8_t cos_bit_to_set = (1 << max_num_of_cos) - 1;
1053
1054         /* Set all the strict priority first */
1055         for (i = 0; i < max_num_of_cos; i++) {
1056                 if (sp_pri_to_cos[i] != DCBX_INVALID_COS) {
1057                         if (sp_pri_to_cos[i] >= DCBX_MAX_NUM_COS) {
1058                                 DP(NETIF_MSG_LINK,
1059                                            "bnx2x_ets_e3b0_sp_set_pri_cli_reg "
1060                                            "invalid cos entry\n");
1061                                 return -EINVAL;
1062                         }
1063
1064                         pri_cli_nig |= bnx2x_e3b0_sp_get_pri_cli_reg_nig(
1065                             sp_pri_to_cos[i], pri_set);
1066
1067                         pri_cli_pbf |= bnx2x_e3b0_sp_get_pri_cli_reg_pbf(
1068                             sp_pri_to_cos[i], pri_set);
1069                         pri_bitmask = 1 << sp_pri_to_cos[i];
1070                         /* COS is used remove it from bitmap.*/
1071                         if (!(pri_bitmask & cos_bit_to_set)) {
1072                                 DP(NETIF_MSG_LINK,
1073                                         "bnx2x_ets_e3b0_sp_set_pri_cli_reg "
1074                                         "invalid There can't be two COS's with"
1075                                         " the same strict pri\n");
1076                                 return -EINVAL;
1077                         }
1078                         cos_bit_to_set &= ~pri_bitmask;
1079                         pri_set++;
1080                 }
1081         }
1082
1083         /* Set all the Non strict priority i= COS*/
1084         for (i = 0; i < max_num_of_cos; i++) {
1085                 pri_bitmask = 1 << i;
1086                 /* Check if COS was already used for SP */
1087                 if (pri_bitmask & cos_bit_to_set) {
1088                         /* COS wasn't used for SP */
1089                         pri_cli_nig |= bnx2x_e3b0_sp_get_pri_cli_reg_nig(
1090                             i, pri_set);
1091
1092                         pri_cli_pbf |= bnx2x_e3b0_sp_get_pri_cli_reg_pbf(
1093                             i, pri_set);
1094                         /* COS is used remove it from bitmap.*/
1095                         cos_bit_to_set &= ~pri_bitmask;
1096                         pri_set++;
1097                 }
1098         }
1099
1100         if (pri_set != max_num_of_cos) {
1101                 DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_set_pri_cli_reg not all "
1102                                    "entries were set\n");
1103                 return -EINVAL;
1104         }
1105
1106         if (port) {
1107                 /* Only 6 usable clients*/
1108                 REG_WR(bp, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_LSB,
1109                        (uint32_t)pri_cli_nig);
1110
1111                 REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P1 , pri_cli_pbf);
1112         } else {
1113                 /* Only 9 usable clients*/
1114                 const uint32_t pri_cli_nig_lsb = (uint32_t) (pri_cli_nig);
1115                 const uint32_t pri_cli_nig_msb = (uint32_t) ((pri_cli_nig >> 32) & 0xF);
1116
1117                 REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_LSB,
1118                        pri_cli_nig_lsb);
1119                 REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_MSB,
1120                        pri_cli_nig_msb);
1121
1122                 REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P0 , pri_cli_pbf);
1123         }
1124         return 0;
1125 }
1126
1127 /******************************************************************************
1128 * Description:
1129 *       Configure the COS to ETS according to BW and SP settings.
1130 ******************************************************************************/
1131 int bnx2x_ets_e3b0_config(const struct link_params *params,
1132                          const struct link_vars *vars,
1133                          struct bnx2x_ets_params *ets_params)
1134 {
1135         struct bnx2x *bp = params->bp;
1136         int bnx2x_status = 0;
1137         const uint8_t port = params->port;
1138         uint16_t total_bw = 0;
1139         const uint32_t min_w_val_nig = bnx2x_ets_get_min_w_val_nig(vars);
1140         const uint32_t min_w_val_pbf = ETS_E3B0_PBF_MIN_W_VAL;
1141         uint8_t cos_bw_bitmap = 0;
1142         uint8_t cos_sp_bitmap = 0;
1143         uint8_t sp_pri_to_cos[DCBX_MAX_NUM_COS] = {0};
1144         const uint8_t max_num_of_cos = (port) ? DCBX_E3B0_MAX_NUM_COS_PORT1 :
1145                 DCBX_E3B0_MAX_NUM_COS_PORT0;
1146         uint8_t cos_entry = 0;
1147
1148         if (!CHIP_IS_E3B0(bp)) {
1149                 DP(NETIF_MSG_LINK,
1150                    "bnx2x_ets_e3b0_disabled the chip isn't E3B0\n");
1151                 return -EINVAL;
1152         }
1153
1154         if ((ets_params->num_of_cos > max_num_of_cos)) {
1155                 DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config the number of COS "
1156                                    "isn't supported\n");
1157                 return -EINVAL;
1158         }
1159
1160         /* Prepare sp strict priority parameters*/
1161         bnx2x_ets_e3b0_sp_pri_to_cos_init(sp_pri_to_cos);
1162
1163         /* Prepare BW parameters*/
1164         bnx2x_status = bnx2x_ets_e3b0_get_total_bw(params, ets_params,
1165                                                    &total_bw);
1166         if (bnx2x_status) {
1167                 DP(NETIF_MSG_LINK,
1168                    "bnx2x_ets_E3B0_config get_total_bw failed\n");
1169                 return -EINVAL;
1170         }
1171
1172         /* Upper bound is set according to current link speed (min_w_val
1173          * should be the same for upper bound and COS credit val).
1174          */
1175         bnx2x_ets_e3b0_set_credit_upper_bound_nig(params, min_w_val_nig);
1176         bnx2x_ets_e3b0_set_credit_upper_bound_pbf(params, min_w_val_pbf);
1177
1178
1179         for (cos_entry = 0; cos_entry < ets_params->num_of_cos; cos_entry++) {
1180                 if (bnx2x_cos_state_bw == ets_params->cos[cos_entry].state) {
1181                         cos_bw_bitmap |= (1 << cos_entry);
1182                         /* The function also sets the BW in HW(not the mappin
1183                          * yet)
1184                          */
1185                         bnx2x_status = bnx2x_ets_e3b0_set_cos_bw(
1186                                 bp, cos_entry, min_w_val_nig, min_w_val_pbf,
1187                                 total_bw,
1188                                 ets_params->cos[cos_entry].params.bw_params.bw,
1189                                  port);
1190                 } else if (bnx2x_cos_state_strict ==
1191                         ets_params->cos[cos_entry].state){
1192                         cos_sp_bitmap |= (1 << cos_entry);
1193
1194                         bnx2x_status = bnx2x_ets_e3b0_sp_pri_to_cos_set(
1195                                 params,
1196                                 sp_pri_to_cos,
1197                                 ets_params->cos[cos_entry].params.sp_params.pri,
1198                                 cos_entry);
1199
1200                 } else {
1201                         DP(NETIF_MSG_LINK,
1202                            "bnx2x_ets_e3b0_config cos state not valid\n");
1203                         return -EINVAL;
1204                 }
1205                 if (bnx2x_status) {
1206                         DP(NETIF_MSG_LINK,
1207                            "bnx2x_ets_e3b0_config set cos bw failed\n");
1208                         return bnx2x_status;
1209                 }
1210         }
1211
1212         /* Set SP register (which COS has higher priority) */
1213         bnx2x_status = bnx2x_ets_e3b0_sp_set_pri_cli_reg(params,
1214                                                          sp_pri_to_cos);
1215
1216         if (bnx2x_status) {
1217                 DP(NETIF_MSG_LINK,
1218                    "bnx2x_ets_E3B0_config set_pri_cli_reg failed\n");
1219                 return bnx2x_status;
1220         }
1221
1222         /* Set client mapping of BW and strict */
1223         bnx2x_status = bnx2x_ets_e3b0_cli_map(params, ets_params,
1224                                               cos_sp_bitmap,
1225                                               cos_bw_bitmap);
1226
1227         if (bnx2x_status) {
1228                 DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config SP failed\n");
1229                 return bnx2x_status;
1230         }
1231         return 0;
1232 }
1233 static void bnx2x_ets_bw_limit_common(const struct link_params *params)
1234 {
1235         /* ETS disabled configuration */
1236         struct bnx2x *bp = params->bp;
1237         DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n");
1238         /* Defines which entries (clients) are subjected to WFQ arbitration
1239          * COS0 0x8
1240          * COS1 0x10
1241          */
1242         REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0x18);
1243         /* Mapping between the ARB_CREDIT_WEIGHT registers and actual
1244          * client numbers (WEIGHT_0 does not actually have to represent
1245          * client 0)
1246          *    PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
1247          *  cos1-001     cos0-000     dbg1-100     dbg0-011     MCP-010
1248          */
1249         REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0x111A);
1250
1251         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0,
1252                ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1253         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1,
1254                ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1255
1256         /* ETS mode enabled*/
1257         REG_WR(bp, PBF_REG_ETS_ENABLED, 1);
1258
1259         /* Defines the number of consecutive slots for the strict priority */
1260         REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
1261         /* Bitmap of 5bits length. Each bit specifies whether the entry behaves
1262          * as strict.  Bits 0,1,2 - debug and management entries, 3 - COS0
1263          * entry, 4 - COS1 entry.
1264          * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
1265          * bit4   bit3    bit2     bit1    bit0
1266          * MCP and debug are strict
1267          */
1268         REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
1269
1270         /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter.*/
1271         REG_WR(bp, PBF_REG_COS0_UPPER_BOUND,
1272                ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1273         REG_WR(bp, PBF_REG_COS1_UPPER_BOUND,
1274                ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1275 }
1276
1277 void bnx2x_ets_bw_limit(const struct link_params *params,
1278                         const uint32_t cos0_bw,
1279                         const uint32_t cos1_bw)
1280 {
1281         /* ETS disabled configuration*/
1282         struct bnx2x *bp = params->bp;
1283         const uint32_t total_bw = cos0_bw + cos1_bw;
1284         uint32_t cos0_credit_weight = 0;
1285         uint32_t cos1_credit_weight = 0;
1286
1287         DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n");
1288
1289         if ((!total_bw) ||
1290             (!cos0_bw) ||
1291             (!cos1_bw)) {
1292                 DP(NETIF_MSG_LINK, "Total BW can't be zero\n");
1293                 return;
1294         }
1295
1296         cos0_credit_weight = (cos0_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/
1297                 total_bw;
1298         cos1_credit_weight = (cos1_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/
1299                 total_bw;
1300
1301         bnx2x_ets_bw_limit_common(params);
1302
1303         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, cos0_credit_weight);
1304         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, cos1_credit_weight);
1305
1306         REG_WR(bp, PBF_REG_COS0_WEIGHT, cos0_credit_weight);
1307         REG_WR(bp, PBF_REG_COS1_WEIGHT, cos1_credit_weight);
1308 }
1309
1310 int bnx2x_ets_strict(const struct link_params *params,
1311                      const uint8_t strict_cos)
1312 {
1313         /* ETS disabled configuration*/
1314         struct bnx2x *bp = params->bp;
1315         uint32_t val    = 0;
1316
1317         DP(NETIF_MSG_LINK, "ETS enabled strict configuration\n");
1318         /* Bitmap of 5bits length. Each bit specifies whether the entry behaves
1319          * as strict.  Bits 0,1,2 - debug and management entries,
1320          * 3 - COS0 entry, 4 - COS1 entry.
1321          *  COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
1322          *  bit4   bit3   bit2      bit1     bit0
1323          * MCP and debug are strict
1324          */
1325         REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1F);
1326         /* For strict priority entries defines the number of consecutive slots
1327          * for the highest priority.
1328          */
1329         REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
1330         /* ETS mode disable */
1331         REG_WR(bp, PBF_REG_ETS_ENABLED, 0);
1332         /* Defines the number of consecutive slots for the strict priority */
1333         REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0x100);
1334
1335         /* Defines the number of consecutive slots for the strict priority */
1336         REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, strict_cos);
1337
1338         /* Mapping between entry  priority to client number (0,1,2 -debug and
1339          * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
1340          * 3bits client num.
1341          *   PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
1342          * dbg0-010     dbg1-001     cos1-100     cos0-011     MCP-000
1343          * dbg0-010     dbg1-001     cos0-011     cos1-100     MCP-000
1344          */
1345         val = (!strict_cos) ? 0x2318 : 0x22E0;
1346         REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, val);
1347
1348         return 0;
1349 }
1350
1351 /******************************************************************/
1352 /*                      PFC section                               */
1353 /******************************************************************/
1354 static void bnx2x_update_pfc_xmac(struct link_params *params,
1355                                   struct link_vars *vars,
1356                                   uint8_t is_lb)
1357 {
1358         struct bnx2x *bp = params->bp;
1359         uint32_t xmac_base;
1360         uint32_t pause_val, pfc0_val, pfc1_val;
1361
1362         /* XMAC base adrr */
1363         xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
1364
1365         /* Initialize pause and pfc registers */
1366         pause_val = 0x18000;
1367         pfc0_val = 0xFFFF8000;
1368         pfc1_val = 0x2;
1369
1370         /* No PFC support */
1371         if (!(params->feature_config_flags &
1372               FEATURE_CONFIG_PFC_ENABLED)) {
1373
1374                 /* RX flow control - Process pause frame in receive direction
1375                  */
1376                 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
1377                         pause_val |= XMAC_PAUSE_CTRL_REG_RX_PAUSE_EN;
1378
1379                 /* TX flow control - Send pause packet when buffer is full */
1380                 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
1381                         pause_val |= XMAC_PAUSE_CTRL_REG_TX_PAUSE_EN;
1382         } else {/* PFC support */
1383                 pfc1_val |= XMAC_PFC_CTRL_HI_REG_PFC_REFRESH_EN |
1384                         XMAC_PFC_CTRL_HI_REG_PFC_STATS_EN |
1385                         XMAC_PFC_CTRL_HI_REG_RX_PFC_EN |
1386                         XMAC_PFC_CTRL_HI_REG_TX_PFC_EN |
1387                         XMAC_PFC_CTRL_HI_REG_FORCE_PFC_XON;
1388                 /* Write pause and PFC registers */
1389                 REG_WR(bp, xmac_base + XMAC_REG_PAUSE_CTRL, pause_val);
1390                 REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL, pfc0_val);
1391                 REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI, pfc1_val);
1392                 pfc1_val &= ~XMAC_PFC_CTRL_HI_REG_FORCE_PFC_XON;
1393
1394         }
1395
1396         /* Write pause and PFC registers */
1397         REG_WR(bp, xmac_base + XMAC_REG_PAUSE_CTRL, pause_val);
1398         REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL, pfc0_val);
1399         REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI, pfc1_val);
1400
1401
1402         /* Set MAC address for source TX Pause/PFC frames */
1403         REG_WR(bp, xmac_base + XMAC_REG_CTRL_SA_LO,
1404                ((params->mac_addr[2] << 24) |
1405                 (params->mac_addr[3] << 16) |
1406                 (params->mac_addr[4] << 8) |
1407                 (params->mac_addr[5])));
1408         REG_WR(bp, xmac_base + XMAC_REG_CTRL_SA_HI,
1409                ((params->mac_addr[0] << 8) |
1410                 (params->mac_addr[1])));
1411
1412         udelay(30);
1413 }
1414
1415 /******************************************************************/
1416 /*                      MAC/PBF section                           */
1417 /******************************************************************/
1418 static void bnx2x_set_mdio_clk(struct bnx2x *bp, uint32_t chip_id,
1419                                uint32_t emac_base)
1420 {
1421         uint32_t new_mode, cur_mode;
1422         uint32_t clc_cnt;
1423         /* Set clause 45 mode, slow down the MDIO clock to 2.5MHz
1424          * (a value of 49==0x31) and make sure that the AUTO poll is off
1425          */
1426         cur_mode = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
1427
1428         if (USES_WARPCORE(bp))
1429                 clc_cnt = 74L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT;
1430         else
1431                 clc_cnt = 49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT;
1432
1433         if (((cur_mode & EMAC_MDIO_MODE_CLOCK_CNT) == clc_cnt) &&
1434             (cur_mode & (EMAC_MDIO_MODE_CLAUSE_45)))
1435                 return;
1436
1437         new_mode = cur_mode &
1438                 ~(EMAC_MDIO_MODE_AUTO_POLL | EMAC_MDIO_MODE_CLOCK_CNT);
1439         new_mode |= clc_cnt;
1440         new_mode |= (EMAC_MDIO_MODE_CLAUSE_45);
1441
1442         DP(NETIF_MSG_LINK, "Changing emac_mode from 0x%x to 0x%x\n",
1443            cur_mode, new_mode);
1444         REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE, new_mode);
1445         udelay(40);
1446 }
1447
1448 static void bnx2x_set_mdio_emac_per_phy(struct bnx2x *bp,
1449                                         struct link_params *params)
1450 {
1451         uint8_t phy_index;
1452         /* Set mdio clock per phy */
1453         for (phy_index = INT_PHY; phy_index < params->num_phys;
1454               phy_index++)
1455                 bnx2x_set_mdio_clk(bp, params->chip_id,
1456                                    params->phy[phy_index].mdio_ctrl);
1457 }
1458
1459 static uint8_t bnx2x_is_4_port_mode(struct bnx2x *bp)
1460 {
1461         uint32_t port4mode_ovwr_val;
1462         /* Check 4-port override enabled */
1463         port4mode_ovwr_val = REG_RD(bp, MISC_REG_PORT4MODE_EN_OVWR);
1464         if (port4mode_ovwr_val & (1<<0)) {
1465                 /* Return 4-port mode override value */
1466                 return ((port4mode_ovwr_val & (1<<1)) == (1<<1));
1467         }
1468         /* Return 4-port mode from input pin */
1469         return (uint8_t)REG_RD(bp, MISC_REG_PORT4MODE_EN);
1470 }
1471
1472 static void bnx2x_emac_init(struct link_params *params,
1473                             struct link_vars *vars)
1474 {
1475         /* reset and unreset the emac core */
1476         struct bnx2x *bp = params->bp;
1477         uint8_t port = params->port;
1478         uint32_t emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1479         uint32_t val;
1480         uint16_t timeout;
1481
1482         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1483                (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
1484         udelay(5);
1485         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1486                (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
1487
1488         /* init emac - use read-modify-write */
1489         /* self clear reset */
1490         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
1491         EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
1492
1493         timeout = 200;
1494         do {
1495                 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
1496                 DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
1497                 if (!timeout) {
1498                         DP(NETIF_MSG_LINK, "EMAC timeout!\n");
1499                         return;
1500                 }
1501                 timeout--;
1502         } while (val & EMAC_MODE_RESET);
1503
1504         bnx2x_set_mdio_emac_per_phy(bp, params);
1505         /* Set mac address */
1506         val = ((params->mac_addr[0] << 8) |
1507                 params->mac_addr[1]);
1508         EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH, val);
1509
1510         val = ((params->mac_addr[2] << 24) |
1511                (params->mac_addr[3] << 16) |
1512                (params->mac_addr[4] << 8) |
1513                 params->mac_addr[5]);
1514         EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val);
1515 }
1516
1517 static void bnx2x_set_xumac_nig(struct link_params *params,
1518                                 uint16_t tx_pause_en,
1519                                 uint8_t enable)
1520 {
1521         struct bnx2x *bp = params->bp;
1522
1523         REG_WR(bp, params->port ? NIG_REG_P1_MAC_IN_EN : NIG_REG_P0_MAC_IN_EN,
1524                enable);
1525         REG_WR(bp, params->port ? NIG_REG_P1_MAC_OUT_EN : NIG_REG_P0_MAC_OUT_EN,
1526                enable);
1527         REG_WR(bp, params->port ? NIG_REG_P1_MAC_PAUSE_OUT_EN :
1528                NIG_REG_P0_MAC_PAUSE_OUT_EN, tx_pause_en);
1529 }
1530
1531 static void bnx2x_set_umac_rxtx(struct link_params *params, uint8_t en)
1532 {
1533         uint32_t umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
1534         uint32_t val;
1535         struct bnx2x *bp = params->bp;
1536         if (!(REG_RD(bp, MISC_REG_RESET_REG_2) &
1537                    (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port)))
1538                 return;
1539         val = REG_RD(bp, umac_base + UMAC_REG_COMMAND_CONFIG);
1540         if (en)
1541                 val |= (UMAC_COMMAND_CONFIG_REG_TX_ENA |
1542                         UMAC_COMMAND_CONFIG_REG_RX_ENA);
1543         else
1544                 val &= ~(UMAC_COMMAND_CONFIG_REG_TX_ENA |
1545                          UMAC_COMMAND_CONFIG_REG_RX_ENA);
1546         /* Disable RX and TX */
1547         REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);
1548 }
1549
1550 static void bnx2x_umac_enable(struct link_params *params,
1551                             struct link_vars *vars, uint8_t lb)
1552 {
1553         uint32_t val;
1554         uint32_t umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
1555         struct bnx2x *bp = params->bp;
1556         /* Reset UMAC */
1557         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1558                (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port));
1559         kthread_usleep(1000);
1560
1561         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1562                (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port));
1563
1564         DP(NETIF_MSG_LINK, "enabling UMAC\n");
1565
1566         /* This register opens the gate for the UMAC despite its name */
1567         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 1);
1568
1569         val = UMAC_COMMAND_CONFIG_REG_PROMIS_EN |
1570                 UMAC_COMMAND_CONFIG_REG_PAD_EN |
1571                 UMAC_COMMAND_CONFIG_REG_SW_RESET |
1572                 UMAC_COMMAND_CONFIG_REG_NO_LGTH_CHECK;
1573         switch (vars->line_speed) {
1574         case SPEED_10:
1575                 val |= (0<<2);
1576                 break;
1577         case SPEED_100:
1578                 val |= (1<<2);
1579                 break;
1580         case SPEED_1000:
1581                 val |= (2<<2);
1582                 break;
1583         case SPEED_2500:
1584                 val |= (3<<2);
1585                 break;
1586         default:
1587                 DP(NETIF_MSG_LINK, "Invalid speed for UMAC %d\n",
1588                                vars->line_speed);
1589                 break;
1590         }
1591         if (!(vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1592                 val |= UMAC_COMMAND_CONFIG_REG_IGNORE_TX_PAUSE;
1593
1594         if (!(vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
1595                 val |= UMAC_COMMAND_CONFIG_REG_PAUSE_IGNORE;
1596
1597         if (vars->duplex == DUPLEX_HALF)
1598                 val |= UMAC_COMMAND_CONFIG_REG_HD_ENA;
1599
1600         REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);
1601         udelay(50);
1602
1603         /* Configure UMAC for EEE */
1604         if (vars->eee_status & SHMEM_EEE_ADV_STATUS_MASK) {
1605                 DP(NETIF_MSG_LINK, "configured UMAC for EEE\n");
1606                 REG_WR(bp, umac_base + UMAC_REG_UMAC_EEE_CTRL,
1607                        UMAC_UMAC_EEE_CTRL_REG_EEE_EN);
1608                 REG_WR(bp, umac_base + UMAC_REG_EEE_WAKE_TIMER, 0x11);
1609         } else {
1610                 REG_WR(bp, umac_base + UMAC_REG_UMAC_EEE_CTRL, 0x0);
1611         }
1612
1613         /* Set MAC address for source TX Pause/PFC frames (under SW reset) */
1614         REG_WR(bp, umac_base + UMAC_REG_MAC_ADDR0,
1615                ((params->mac_addr[2] << 24) |
1616                 (params->mac_addr[3] << 16) |
1617                 (params->mac_addr[4] << 8) |
1618                 (params->mac_addr[5])));
1619         REG_WR(bp, umac_base + UMAC_REG_MAC_ADDR1,
1620                ((params->mac_addr[0] << 8) |
1621                 (params->mac_addr[1])));
1622
1623         /* Enable RX and TX */
1624         val &= ~UMAC_COMMAND_CONFIG_REG_PAD_EN;
1625         val |= UMAC_COMMAND_CONFIG_REG_TX_ENA |
1626                 UMAC_COMMAND_CONFIG_REG_RX_ENA;
1627         REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);
1628         udelay(50);
1629
1630         /* Remove SW Reset */
1631         val &= ~UMAC_COMMAND_CONFIG_REG_SW_RESET;
1632
1633         /* Check loopback mode */
1634         if (lb)
1635                 val |= UMAC_COMMAND_CONFIG_REG_LOOP_ENA;
1636         REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);
1637
1638         /* Maximum Frame Length (RW). Defines a 14-Bit maximum frame
1639          * length used by the MAC receive logic to check frames.
1640          */
1641         REG_WR(bp, umac_base + UMAC_REG_MAXFR, 0x2710);
1642         bnx2x_set_xumac_nig(params,
1643                             ((vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) != 0), 1);
1644         vars->mac_type = MAC_TYPE_UMAC;
1645
1646 }
1647
1648 /* Define the XMAC mode */
1649 static void bnx2x_xmac_init(struct link_params *params, uint32_t max_speed)
1650 {
1651         struct bnx2x *bp = params->bp;
1652         uint32_t is_port4mode = bnx2x_is_4_port_mode(bp);
1653
1654         /* In 4-port mode, need to set the mode only once, so if XMAC is
1655          * already out of reset, it means the mode has already been set,
1656          * and it must not* reset the XMAC again, since it controls both
1657          * ports of the path
1658          */
1659
1660         if (((CHIP_NUM(bp) == CHIP_NUM_57840_4_10) ||
1661              (CHIP_NUM(bp) == CHIP_NUM_57840_2_20) ||
1662              (CHIP_NUM(bp) == CHIP_NUM_57840_OBSOLETE)) &&
1663             is_port4mode &&
1664             (REG_RD(bp, MISC_REG_RESET_REG_2) &
1665              MISC_REGISTERS_RESET_REG_2_XMAC)) {
1666                 DP(NETIF_MSG_LINK,
1667                    "XMAC already out of reset in 4-port mode\n");
1668                 return;
1669         }
1670
1671         /* Hard reset */
1672         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1673                MISC_REGISTERS_RESET_REG_2_XMAC);
1674         kthread_usleep(1000);
1675
1676         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1677                MISC_REGISTERS_RESET_REG_2_XMAC);
1678         if (is_port4mode) {
1679                 DP(NETIF_MSG_LINK, "Init XMAC to 2 ports x 10G per path\n");
1680
1681                 /* Set the number of ports on the system side to up to 2 */
1682                 REG_WR(bp, MISC_REG_XMAC_CORE_PORT_MODE, 1);
1683
1684                 /* Set the number of ports on the Warp Core to 10G */
1685                 REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 3);
1686         } else {
1687                 /* Set the number of ports on the system side to 1 */
1688                 REG_WR(bp, MISC_REG_XMAC_CORE_PORT_MODE, 0);
1689                 if (max_speed == SPEED_10000) {
1690                         DP(NETIF_MSG_LINK,
1691                            "Init XMAC to 10G x 1 port per path\n");
1692                         /* Set the number of ports on the Warp Core to 10G */
1693                         REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 3);
1694                 } else {
1695                         DP(NETIF_MSG_LINK,
1696                            "Init XMAC to 20G x 2 ports per path\n");
1697                         /* Set the number of ports on the Warp Core to 20G */
1698                         REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 1);
1699                 }
1700         }
1701         /* Soft reset */
1702         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1703                MISC_REGISTERS_RESET_REG_2_XMAC_SOFT);
1704         kthread_usleep(1000);
1705
1706         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1707                MISC_REGISTERS_RESET_REG_2_XMAC_SOFT);
1708
1709 }
1710
1711 static void bnx2x_set_xmac_rxtx(struct link_params *params, uint8_t en)
1712 {
1713         uint8_t port = params->port;
1714         struct bnx2x *bp = params->bp;
1715         uint32_t pfc_ctrl, xmac_base = (port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
1716         uint32_t val;
1717
1718         if (REG_RD(bp, MISC_REG_RESET_REG_2) &
1719             MISC_REGISTERS_RESET_REG_2_XMAC) {
1720                 /* Send an indication to change the state in the NIG back to XON
1721                  * Clearing this bit enables the next set of this bit to get
1722                  * rising edge
1723                  */
1724                 pfc_ctrl = REG_RD(bp, xmac_base + XMAC_REG_PFC_CTRL_HI);
1725                 REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI,
1726                        (pfc_ctrl & ~(1<<1)));
1727                 REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI,
1728                        (pfc_ctrl | (1<<1)));
1729                 DP(NETIF_MSG_LINK, "Disable XMAC on port %x\n", port);
1730                 val = REG_RD(bp, xmac_base + XMAC_REG_CTRL);
1731                 if (en)
1732                         val |= (XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN);
1733                 else
1734                         val &= ~(XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN);
1735                 REG_WR(bp, xmac_base + XMAC_REG_CTRL, val);
1736         }
1737 }
1738
1739 static int bnx2x_xmac_enable(struct link_params *params,
1740                              struct link_vars *vars, uint8_t lb)
1741 {
1742         uint32_t val, xmac_base;
1743         struct bnx2x *bp = params->bp;
1744         DP(NETIF_MSG_LINK, "enabling XMAC\n");
1745
1746         xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
1747
1748         bnx2x_xmac_init(params, vars->line_speed);
1749
1750         /* This register determines on which events the MAC will assert
1751          * error on the i/f to the NIG along w/ EOP.
1752          */
1753
1754         /* This register tells the NIG whether to send traffic to UMAC
1755          * or XMAC
1756          */
1757         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 0);
1758
1759         /* When XMAC is in XLGMII mode, disable sending idles for fault
1760          * detection.
1761          */
1762         if (!(params->phy[INT_PHY].flags & FLAGS_TX_ERROR_CHECK)) {
1763                 REG_WR(bp, xmac_base + XMAC_REG_RX_LSS_CTRL,
1764                        (XMAC_RX_LSS_CTRL_REG_LOCAL_FAULT_DISABLE |
1765                         XMAC_RX_LSS_CTRL_REG_REMOTE_FAULT_DISABLE));
1766                 REG_WR(bp, xmac_base + XMAC_REG_CLEAR_RX_LSS_STATUS, 0);
1767                 REG_WR(bp, xmac_base + XMAC_REG_CLEAR_RX_LSS_STATUS,
1768                        XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_LOCAL_FAULT_STATUS |
1769                        XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_REMOTE_FAULT_STATUS);
1770         }
1771         /* Set Max packet size */
1772         REG_WR(bp, xmac_base + XMAC_REG_RX_MAX_SIZE, 0x2710);
1773
1774         /* CRC append for Tx packets */
1775         REG_WR(bp, xmac_base + XMAC_REG_TX_CTRL, 0xC800);
1776
1777         /* update PFC */
1778         bnx2x_update_pfc_xmac(params, vars, 0);
1779
1780         if (vars->eee_status & SHMEM_EEE_ADV_STATUS_MASK) {
1781                 DP(NETIF_MSG_LINK, "Setting XMAC for EEE\n");
1782                 REG_WR(bp, xmac_base + XMAC_REG_EEE_TIMERS_HI, 0x1380008);
1783                 REG_WR(bp, xmac_base + XMAC_REG_EEE_CTRL, 0x1);
1784         } else {
1785                 REG_WR(bp, xmac_base + XMAC_REG_EEE_CTRL, 0x0);
1786         }
1787
1788         /* Enable TX and RX */
1789         val = XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN;
1790
1791         /* Set MAC in XLGMII mode for dual-mode */
1792         if ((vars->line_speed == SPEED_20000) &&
1793             (params->phy[INT_PHY].supported &
1794              SUPPORTED_20000baseKR2_Full))
1795                 val |= XMAC_CTRL_REG_XLGMII_ALIGN_ENB;
1796
1797         /* Check loopback mode */
1798         if (lb)
1799                 val |= XMAC_CTRL_REG_LINE_LOCAL_LPBK;
1800         REG_WR(bp, xmac_base + XMAC_REG_CTRL, val);
1801         bnx2x_set_xumac_nig(params,
1802                             ((vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) != 0), 1);
1803
1804         vars->mac_type = MAC_TYPE_XMAC;
1805
1806         return 0;
1807 }
1808
1809 static int bnx2x_emac_enable(struct link_params *params,
1810                              struct link_vars *vars, uint8_t lb)
1811 {
1812         struct bnx2x *bp = params->bp;
1813         uint8_t port = params->port;
1814         uint32_t emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1815         uint32_t val;
1816
1817         DP(NETIF_MSG_LINK, "enabling EMAC\n");
1818
1819         /* Disable BMAC */
1820         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1821                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
1822
1823         /* enable emac and not bmac */
1824         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
1825
1826         /* ASIC */
1827         if (vars->phy_flags & PHY_XGXS_FLAG) {
1828                 uint32_t ser_lane = ((params->lane_config &
1829                                  PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1830                                 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1831
1832                 DP(NETIF_MSG_LINK, "XGXS\n");
1833                 /* select the master lanes (out of 0-3) */
1834                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, ser_lane);
1835                 /* select XGXS */
1836                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
1837
1838         } else { /* SerDes */
1839                 DP(NETIF_MSG_LINK, "SerDes\n");
1840                 /* select SerDes */
1841                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0);
1842         }
1843
1844         bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
1845                       EMAC_RX_MODE_RESET);
1846         bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
1847                       EMAC_TX_MODE_RESET);
1848
1849                 /* pause enable/disable */
1850                 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
1851                                EMAC_RX_MODE_FLOW_EN);
1852
1853                 bnx2x_bits_dis(bp,  emac_base + EMAC_REG_EMAC_TX_MODE,
1854                                (EMAC_TX_MODE_EXT_PAUSE_EN |
1855                                 EMAC_TX_MODE_FLOW_EN));
1856                 if (!(params->feature_config_flags &
1857                       FEATURE_CONFIG_PFC_ENABLED)) {
1858                         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
1859                                 bnx2x_bits_en(bp, emac_base +
1860                                               EMAC_REG_EMAC_RX_MODE,
1861                                               EMAC_RX_MODE_FLOW_EN);
1862
1863                         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
1864                                 bnx2x_bits_en(bp, emac_base +
1865                                               EMAC_REG_EMAC_TX_MODE,
1866                                               (EMAC_TX_MODE_EXT_PAUSE_EN |
1867                                                EMAC_TX_MODE_FLOW_EN));
1868                 } else
1869                         bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
1870                                       EMAC_TX_MODE_FLOW_EN);
1871
1872         /* KEEP_VLAN_TAG, promiscuous */
1873         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
1874         val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
1875
1876         /* Setting this bit causes MAC control frames (except for pause
1877          * frames) to be passed on for processing. This setting has no
1878          * affect on the operation of the pause frames. This bit effects
1879          * all packets regardless of RX Parser packet sorting logic.
1880          * Turn the PFC off to make sure we are in Xon state before
1881          * enabling it.
1882          */
1883         EMAC_WR(bp, EMAC_REG_RX_PFC_MODE, 0);
1884         if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) {
1885                 DP(NETIF_MSG_LINK, "PFC is enabled\n");
1886                 /* Enable PFC again */
1887                 EMAC_WR(bp, EMAC_REG_RX_PFC_MODE,
1888                         EMAC_REG_RX_PFC_MODE_RX_EN |
1889                         EMAC_REG_RX_PFC_MODE_TX_EN |
1890                         EMAC_REG_RX_PFC_MODE_PRIORITIES);
1891
1892                 EMAC_WR(bp, EMAC_REG_RX_PFC_PARAM,
1893                         ((0x0101 <<
1894                           EMAC_REG_RX_PFC_PARAM_OPCODE_BITSHIFT) |
1895                          (0x00ff <<
1896                           EMAC_REG_RX_PFC_PARAM_PRIORITY_EN_BITSHIFT)));
1897                 val |= EMAC_RX_MODE_KEEP_MAC_CONTROL;
1898         }
1899         EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
1900
1901         /* Set Loopback */
1902         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
1903         if (lb)
1904                 val |= 0x810;
1905         else
1906                 val &= ~0x810;
1907         EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
1908
1909         /* Enable emac */
1910         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
1911
1912         /* Enable emac for jumbo packets */
1913         EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
1914                 (EMAC_RX_MTU_SIZE_JUMBO_ENA |
1915                  (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
1916
1917         /* Strip CRC */
1918         REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
1919
1920         /* Disable the NIG in/out to the bmac */
1921         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
1922         REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
1923         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
1924
1925         /* Enable the NIG in/out to the emac */
1926         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
1927         val = 0;
1928         if ((params->feature_config_flags &
1929               FEATURE_CONFIG_PFC_ENABLED) ||
1930             (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1931                 val = 1;
1932
1933         REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
1934         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
1935
1936         REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x0);
1937
1938         vars->mac_type = MAC_TYPE_EMAC;
1939         return 0;
1940 }
1941
1942 static void bnx2x_update_pfc_bmac1(struct link_params *params,
1943                                    struct link_vars *vars)
1944 {
1945         uint32_t wb_data[2];
1946         struct bnx2x *bp = params->bp;
1947         uint32_t bmac_addr =  params->port ? NIG_REG_INGRESS_BMAC1_MEM :
1948                 NIG_REG_INGRESS_BMAC0_MEM;
1949
1950         uint32_t val = 0x14;
1951         if ((!(params->feature_config_flags &
1952               FEATURE_CONFIG_PFC_ENABLED)) &&
1953                 (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
1954                 /* Enable BigMAC to react on received Pause packets */
1955                 val |= (1<<5);
1956         wb_data[0] = val;
1957         wb_data[1] = 0;
1958         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL, wb_data, 2);
1959
1960         /* TX control */
1961         val = 0xc0;
1962         if (!(params->feature_config_flags &
1963               FEATURE_CONFIG_PFC_ENABLED) &&
1964                 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1965                 val |= 0x800000;
1966         wb_data[0] = val;
1967         wb_data[1] = 0;
1968         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL, wb_data, 2);
1969 }
1970
1971 static void bnx2x_update_pfc_bmac2(struct link_params *params,
1972                                    struct link_vars *vars,
1973                                    uint8_t is_lb)
1974 {
1975         /* Set rx control: Strip CRC and enable BigMAC to relay
1976          * control packets to the system as well
1977          */
1978         uint32_t wb_data[2];
1979         struct bnx2x *bp = params->bp;
1980         uint32_t bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
1981                 NIG_REG_INGRESS_BMAC0_MEM;
1982         uint32_t val = 0x14;
1983
1984         if ((!(params->feature_config_flags &
1985               FEATURE_CONFIG_PFC_ENABLED)) &&
1986                 (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
1987                 /* Enable BigMAC to react on received Pause packets */
1988                 val |= (1<<5);
1989         wb_data[0] = val;
1990         wb_data[1] = 0;
1991         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_CONTROL, wb_data, 2);
1992         udelay(30);
1993
1994         /* Tx control */
1995         val = 0xc0;
1996         if (!(params->feature_config_flags &
1997                                 FEATURE_CONFIG_PFC_ENABLED) &&
1998             (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1999                 val |= 0x800000;
2000         wb_data[0] = val;
2001         wb_data[1] = 0;
2002         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL, wb_data, 2);
2003
2004         if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) {
2005                 DP(NETIF_MSG_LINK, "PFC is enabled\n");
2006                 /* Enable PFC RX & TX & STATS and set 8 COS  */
2007                 wb_data[0] = 0x0;
2008                 wb_data[0] |= (1<<0);  /* RX */
2009                 wb_data[0] |= (1<<1);  /* TX */
2010                 wb_data[0] |= (1<<2);  /* Force initial Xon */
2011                 wb_data[0] |= (1<<3);  /* 8 cos */
2012                 wb_data[0] |= (1<<5);  /* STATS */
2013                 wb_data[1] = 0;
2014                 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL,
2015                             wb_data, 2);
2016                 /* Clear the force Xon */
2017                 wb_data[0] &= ~(1<<2);
2018         } else {
2019                 DP(NETIF_MSG_LINK, "PFC is disabled\n");
2020                 /* Disable PFC RX & TX & STATS and set 8 COS */
2021                 wb_data[0] = 0x8;
2022                 wb_data[1] = 0;
2023         }
2024
2025         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL, wb_data, 2);
2026
2027         /* Set Time (based unit is 512 bit time) between automatic
2028          * re-sending of PP packets amd enable automatic re-send of
2029          * Per-Priroity Packet as long as pp_gen is asserted and
2030          * pp_disable is low.
2031          */
2032         val = 0x8000;
2033         if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
2034                 val |= (1<<16); /* enable automatic re-send */
2035
2036         wb_data[0] = val;
2037         wb_data[1] = 0;
2038         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL,
2039                     wb_data, 2);
2040
2041         /* mac control */
2042         val = 0x3; /* Enable RX and TX */
2043         if (is_lb) {
2044                 val |= 0x4; /* Local loopback */
2045                 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
2046         }
2047         /* When PFC enabled, Pass pause frames towards the NIG. */
2048         if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
2049                 val |= ((1<<6)|(1<<5));
2050
2051         wb_data[0] = val;
2052         wb_data[1] = 0;
2053         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
2054 }
2055
2056 /******************************************************************************
2057 * Description:
2058 *  This function is needed because NIG ARB_CREDIT_WEIGHT_X are
2059 *  not continues and ARB_CREDIT_WEIGHT_0 + offset is suitable.
2060 ******************************************************************************/
2061 static int bnx2x_pfc_nig_rx_priority_mask(struct bnx2x *bp,
2062                                            uint8_t cos_entry,
2063                                            uint32_t priority_mask,
2064                                           uint8_t port)
2065 {
2066         uint32_t nig_reg_rx_priority_mask_add = 0;
2067
2068         switch (cos_entry) {
2069         case 0:
2070              nig_reg_rx_priority_mask_add = (port) ?
2071                  NIG_REG_P1_RX_COS0_PRIORITY_MASK :
2072                  NIG_REG_P0_RX_COS0_PRIORITY_MASK;
2073              break;
2074         case 1:
2075             nig_reg_rx_priority_mask_add = (port) ?
2076                 NIG_REG_P1_RX_COS1_PRIORITY_MASK :
2077                 NIG_REG_P0_RX_COS1_PRIORITY_MASK;
2078             break;
2079         case 2:
2080             nig_reg_rx_priority_mask_add = (port) ?
2081                 NIG_REG_P1_RX_COS2_PRIORITY_MASK :
2082                 NIG_REG_P0_RX_COS2_PRIORITY_MASK;
2083             break;
2084         case 3:
2085             if (port)
2086                 return -EINVAL;
2087             nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS3_PRIORITY_MASK;
2088             break;
2089         case 4:
2090             if (port)
2091                 return -EINVAL;
2092             nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS4_PRIORITY_MASK;
2093             break;
2094         case 5:
2095             if (port)
2096                 return -EINVAL;
2097             nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS5_PRIORITY_MASK;
2098             break;
2099         }
2100
2101         REG_WR(bp, nig_reg_rx_priority_mask_add, priority_mask);
2102
2103         return 0;
2104 }
2105 static void bnx2x_update_mng(struct link_params *params, uint32_t link_status)
2106 {
2107         struct bnx2x *bp = params->bp;
2108
2109         REG_WR(bp, params->shmem_base +
2110                offsetof(struct shmem_region,
2111                         port_mb[params->port].link_status), link_status);
2112 }
2113
2114 static void bnx2x_update_link_attr(struct link_params *params,
2115                                    uint32_t link_attr)
2116 {
2117         struct bnx2x *bp = params->bp;
2118
2119         if (SHMEM2_HAS(bp, link_attr_sync))
2120                 REG_WR(bp, params->shmem2_base +
2121                        offsetof(struct shmem2_region,
2122                                 link_attr_sync[params->port]), link_attr);
2123 }
2124
2125 static void bnx2x_update_pfc_nig(struct link_params *params,
2126                 struct link_vars *vars,
2127                 struct bnx2x_nig_brb_pfc_port_params *nig_params)
2128 {
2129         uint32_t xcm_mask = 0, ppp_enable = 0, pause_enable = 0, llfc_out_en = 0;
2130         uint32_t llfc_enable = 0, xcm_out_en = 0, hwpfc_enable = 0;
2131         uint32_t pkt_priority_to_cos = 0;
2132         struct bnx2x *bp = params->bp;
2133         uint8_t port = params->port;
2134
2135         int set_pfc = params->feature_config_flags &
2136                 FEATURE_CONFIG_PFC_ENABLED;
2137         DP(NETIF_MSG_LINK, "updating pfc nig parameters\n");
2138
2139         /* When NIG_LLH0_XCM_MASK_REG_LLHX_XCM_MASK_BCN bit is set
2140          * MAC control frames (that are not pause packets)
2141          * will be forwarded to the XCM.
2142          */
2143         xcm_mask = REG_RD(bp, port ? NIG_REG_LLH1_XCM_MASK :
2144                           NIG_REG_LLH0_XCM_MASK);
2145         /* NIG params will override non PFC params, since it's possible to
2146          * do transition from PFC to SAFC
2147          */
2148         if (set_pfc) {
2149                 pause_enable = 0;
2150                 llfc_out_en = 0;
2151                 llfc_enable = 0;
2152                 if (CHIP_IS_E3(bp))
2153                         ppp_enable = 0;
2154                 else
2155                         ppp_enable = 1;
2156                 xcm_mask &= ~(port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
2157                                      NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
2158                 xcm_out_en = 0;
2159                 hwpfc_enable = 1;
2160         } else  {
2161                 if (nig_params) {
2162                         llfc_out_en = nig_params->llfc_out_en;
2163                         llfc_enable = nig_params->llfc_enable;
2164                         pause_enable = nig_params->pause_enable;
2165                 } else  /* Default non PFC mode - PAUSE */
2166                         pause_enable = 1;
2167
2168                 xcm_mask |= (port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
2169                         NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
2170                 xcm_out_en = 1;
2171         }
2172
2173         if (CHIP_IS_E3(bp))
2174                 REG_WR(bp, port ? NIG_REG_BRB1_PAUSE_IN_EN :
2175                        NIG_REG_BRB0_PAUSE_IN_EN, pause_enable);
2176         REG_WR(bp, port ? NIG_REG_LLFC_OUT_EN_1 :
2177                NIG_REG_LLFC_OUT_EN_0, llfc_out_en);
2178         REG_WR(bp, port ? NIG_REG_LLFC_ENABLE_1 :
2179                NIG_REG_LLFC_ENABLE_0, llfc_enable);
2180         REG_WR(bp, port ? NIG_REG_PAUSE_ENABLE_1 :
2181                NIG_REG_PAUSE_ENABLE_0, pause_enable);
2182
2183         REG_WR(bp, port ? NIG_REG_PPP_ENABLE_1 :
2184                NIG_REG_PPP_ENABLE_0, ppp_enable);
2185
2186         REG_WR(bp, port ? NIG_REG_LLH1_XCM_MASK :
2187                NIG_REG_LLH0_XCM_MASK, xcm_mask);
2188
2189         REG_WR(bp, port ? NIG_REG_LLFC_EGRESS_SRC_ENABLE_1 :
2190                NIG_REG_LLFC_EGRESS_SRC_ENABLE_0, 0x7);
2191
2192         /* Output enable for RX_XCM # IF */
2193         REG_WR(bp, port ? NIG_REG_XCM1_OUT_EN :
2194                NIG_REG_XCM0_OUT_EN, xcm_out_en);
2195
2196         /* HW PFC TX enable */
2197         REG_WR(bp, port ? NIG_REG_P1_HWPFC_ENABLE :
2198                NIG_REG_P0_HWPFC_ENABLE, hwpfc_enable);
2199
2200         if (nig_params) {
2201                 uint8_t i = 0;
2202                 pkt_priority_to_cos = nig_params->pkt_priority_to_cos;
2203
2204                 for (i = 0; i < nig_params->num_of_rx_cos_priority_mask; i++)
2205                         bnx2x_pfc_nig_rx_priority_mask(bp, i,
2206                 nig_params->rx_cos_priority_mask[i], port);
2207
2208                 REG_WR(bp, port ? NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_1 :
2209                        NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0,
2210                        nig_params->llfc_high_priority_classes);
2211
2212                 REG_WR(bp, port ? NIG_REG_LLFC_LOW_PRIORITY_CLASSES_1 :
2213                        NIG_REG_LLFC_LOW_PRIORITY_CLASSES_0,
2214                        nig_params->llfc_low_priority_classes);
2215         }
2216         REG_WR(bp, port ? NIG_REG_P1_PKT_PRIORITY_TO_COS :
2217                NIG_REG_P0_PKT_PRIORITY_TO_COS,
2218                pkt_priority_to_cos);
2219 }
2220
2221 int bnx2x_update_pfc(struct link_params *params,
2222                       struct link_vars *vars,
2223                       struct bnx2x_nig_brb_pfc_port_params *pfc_params)
2224 {
2225         /* The PFC and pause are orthogonal to one another, meaning when
2226          * PFC is enabled, the pause are disabled, and when PFC is
2227          * disabled, pause are set according to the pause result.
2228          */
2229         uint32_t val;
2230         struct bnx2x *bp = params->bp;
2231         uint8_t bmac_loopback = (params->loopback_mode == LOOPBACK_BMAC);
2232
2233         if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
2234                 vars->link_status |= LINK_STATUS_PFC_ENABLED;
2235         else
2236                 vars->link_status &= ~LINK_STATUS_PFC_ENABLED;
2237
2238         bnx2x_update_mng(params, vars->link_status);
2239
2240         /* Update NIG params */
2241         bnx2x_update_pfc_nig(params, vars, pfc_params);
2242
2243         if (!vars->link_up)
2244                 return 0;
2245
2246         DP(NETIF_MSG_LINK, "About to update PFC in BMAC\n");
2247
2248         if (CHIP_IS_E3(bp)) {
2249                 if (vars->mac_type == MAC_TYPE_XMAC)
2250                         bnx2x_update_pfc_xmac(params, vars, 0);
2251         } else {
2252                 val = REG_RD(bp, MISC_REG_RESET_REG_2);
2253                 if ((val &
2254                      (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))
2255                     == 0) {
2256                         DP(NETIF_MSG_LINK, "About to update PFC in EMAC\n");
2257                         bnx2x_emac_enable(params, vars, 0);
2258                         return 0;
2259                 }
2260                 if (CHIP_IS_E2(bp))
2261                         bnx2x_update_pfc_bmac2(params, vars, bmac_loopback);
2262                 else
2263                         bnx2x_update_pfc_bmac1(params, vars);
2264
2265                 val = 0;
2266                 if ((params->feature_config_flags &
2267                      FEATURE_CONFIG_PFC_ENABLED) ||
2268                     (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
2269                         val = 1;
2270                 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + params->port*4, val);
2271         }
2272         return 0;
2273 }
2274
2275 static int bnx2x_bmac1_enable(struct link_params *params,
2276                               struct link_vars *vars,
2277                               uint8_t is_lb)
2278 {
2279         struct bnx2x *bp = params->bp;
2280         uint8_t port = params->port;
2281         uint32_t bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
2282                                NIG_REG_INGRESS_BMAC0_MEM;
2283         uint32_t wb_data[2];
2284         uint32_t val;
2285
2286         DP(NETIF_MSG_LINK, "Enabling BigMAC1\n");
2287
2288         /* XGXS control */
2289         wb_data[0] = 0x3c;
2290         wb_data[1] = 0;
2291         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
2292                     wb_data, 2);
2293
2294         /* TX MAC SA */
2295         wb_data[0] = ((params->mac_addr[2] << 24) |
2296                        (params->mac_addr[3] << 16) |
2297                        (params->mac_addr[4] << 8) |
2298                         params->mac_addr[5]);
2299         wb_data[1] = ((params->mac_addr[0] << 8) |
2300                         params->mac_addr[1]);
2301         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR, wb_data, 2);
2302
2303         /* MAC control */
2304         val = 0x3;
2305         if (is_lb) {
2306                 val |= 0x4;
2307                 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
2308         }
2309         wb_data[0] = val;
2310         wb_data[1] = 0;
2311         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, wb_data, 2);
2312
2313         /* Set rx mtu */
2314         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2315         wb_data[1] = 0;
2316         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE, wb_data, 2);
2317
2318         bnx2x_update_pfc_bmac1(params, vars);
2319
2320         /* Set tx mtu */
2321         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2322         wb_data[1] = 0;
2323         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE, wb_data, 2);
2324
2325         /* Set cnt max size */
2326         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2327         wb_data[1] = 0;
2328         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE, wb_data, 2);
2329
2330         /* Configure SAFC */
2331         wb_data[0] = 0x1000200;
2332         wb_data[1] = 0;
2333         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
2334                     wb_data, 2);
2335
2336         return 0;
2337 }
2338
2339 static int bnx2x_bmac2_enable(struct link_params *params,
2340                               struct link_vars *vars,
2341                               uint8_t is_lb)
2342 {
2343         struct bnx2x *bp = params->bp;
2344         uint8_t port = params->port;
2345         uint32_t bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
2346                                NIG_REG_INGRESS_BMAC0_MEM;
2347         uint32_t wb_data[2];
2348
2349         DP(NETIF_MSG_LINK, "Enabling BigMAC2\n");
2350
2351         wb_data[0] = 0;
2352         wb_data[1] = 0;
2353         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
2354         udelay(30);
2355
2356         /* XGXS control: Reset phy HW, MDIO registers, PHY PLL and BMAC */
2357         wb_data[0] = 0x3c;
2358         wb_data[1] = 0;
2359         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_XGXS_CONTROL,
2360                     wb_data, 2);
2361
2362         udelay(30);
2363
2364         /* TX MAC SA */
2365         wb_data[0] = ((params->mac_addr[2] << 24) |
2366                        (params->mac_addr[3] << 16) |
2367                        (params->mac_addr[4] << 8) |
2368                         params->mac_addr[5]);
2369         wb_data[1] = ((params->mac_addr[0] << 8) |
2370                         params->mac_addr[1]);
2371         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_SOURCE_ADDR,
2372                     wb_data, 2);
2373
2374         udelay(30);
2375
2376         /* Configure SAFC */
2377         wb_data[0] = 0x1000200;
2378         wb_data[1] = 0;
2379         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS,
2380                     wb_data, 2);
2381         udelay(30);
2382
2383         /* Set RX MTU */
2384         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2385         wb_data[1] = 0;
2386         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_MAX_SIZE, wb_data, 2);
2387         udelay(30);
2388
2389         /* Set TX MTU */
2390         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2391         wb_data[1] = 0;
2392         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_MAX_SIZE, wb_data, 2);
2393         udelay(30);
2394         /* Set cnt max size */
2395         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD - 2;
2396         wb_data[1] = 0;
2397         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE, wb_data, 2);
2398         udelay(30);
2399         bnx2x_update_pfc_bmac2(params, vars, is_lb);
2400
2401         return 0;
2402 }
2403
2404 static int bnx2x_bmac_enable(struct link_params *params,
2405                              struct link_vars *vars,
2406                              uint8_t is_lb, uint8_t reset_bmac)
2407 {
2408         int rc = 0;
2409         uint8_t port = params->port;
2410         struct bnx2x *bp = params->bp;
2411         uint32_t val;
2412         /* Reset and unreset the BigMac */
2413         if (reset_bmac) {
2414                 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
2415                        (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
2416                 kthread_usleep(1000);
2417         }
2418
2419         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
2420                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
2421
2422         /* Enable access for bmac registers */
2423         REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
2424
2425         /* Enable BMAC according to BMAC type*/
2426         if (CHIP_IS_E2(bp))
2427                 rc = bnx2x_bmac2_enable(params, vars, is_lb);
2428         else
2429                 rc = bnx2x_bmac1_enable(params, vars, is_lb);
2430         REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
2431         REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
2432         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
2433         val = 0;
2434         if ((params->feature_config_flags &
2435               FEATURE_CONFIG_PFC_ENABLED) ||
2436             (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
2437                 val = 1;
2438         REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
2439         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
2440         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
2441         REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
2442         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
2443         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
2444
2445         vars->mac_type = MAC_TYPE_BMAC;
2446         return rc;
2447 }
2448
2449 static void bnx2x_set_bmac_rx(struct bnx2x *bp, uint32_t chip_id,
2450                               uint8_t port,
2451                               uint8_t en)
2452 {
2453         uint32_t bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
2454                         NIG_REG_INGRESS_BMAC0_MEM;
2455         uint32_t wb_data[2];
2456         uint32_t nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
2457
2458         if (CHIP_IS_E2(bp))
2459                 bmac_addr += BIGMAC2_REGISTER_BMAC_CONTROL;
2460         else
2461                 bmac_addr += BIGMAC_REGISTER_BMAC_CONTROL;
2462         /* Only if the bmac is out of reset */
2463         if (REG_RD(bp, MISC_REG_RESET_REG_2) &
2464                         (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
2465             nig_bmac_enable) {
2466                 /* Clear Rx Enable bit in BMAC_CONTROL register */
2467                 REG_RD_DMAE(bp, bmac_addr, wb_data, 2);
2468                 if (en)
2469                         wb_data[0] |= BMAC_CONTROL_RX_ENABLE;
2470                 else
2471                         wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
2472                 REG_WR_DMAE(bp, bmac_addr, wb_data, 2);
2473                 kthread_usleep(1000);
2474         }
2475 }
2476
2477 static int bnx2x_pbf_update(struct link_params *params, uint32_t flow_ctrl,
2478                             uint32_t line_speed)
2479 {
2480         struct bnx2x *bp = params->bp;
2481         uint8_t port = params->port;
2482         uint32_t init_crd, crd;
2483         uint32_t count = 1000;
2484
2485         /* Disable port */
2486         REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
2487
2488         /* Wait for init credit */
2489         init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
2490         crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
2491         DP(NETIF_MSG_LINK, "init_crd 0x%x  crd 0x%x\n", init_crd, crd);
2492
2493         while ((init_crd != crd) && count) {
2494                 kthread_usleep(5000);
2495                 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
2496                 count--;
2497         }
2498         crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
2499         if (init_crd != crd) {
2500                 DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
2501                           init_crd, crd);
2502                 return -EINVAL;
2503         }
2504
2505         if (flow_ctrl & BNX2X_FLOW_CTRL_RX ||
2506             line_speed == SPEED_10 ||
2507             line_speed == SPEED_100 ||
2508             line_speed == SPEED_1000 ||
2509             line_speed == SPEED_2500) {
2510                 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
2511                 /* Update threshold */
2512                 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
2513                 /* Update init credit */
2514                 init_crd = 778;         /* (800-18-4) */
2515
2516         } else {
2517                 uint32_t thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
2518                               ETH_OVREHEAD)/16;
2519                 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
2520                 /* Update threshold */
2521                 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
2522                 /* Update init credit */
2523                 switch (line_speed) {
2524                 case SPEED_10000:
2525                         init_crd = thresh + 553 - 22;
2526                         break;
2527                 default:
2528                         DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
2529                                   line_speed);
2530                         return -EINVAL;
2531                 }
2532         }
2533         REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
2534         DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
2535                  line_speed, init_crd);
2536
2537         /* Probe the credit changes */
2538         REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
2539         kthread_usleep(5000);
2540         REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
2541
2542         /* Enable port */
2543         REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
2544         return 0;
2545 }
2546
2547 /**
2548  * bnx2x_get_emac_base - retrive emac base address
2549  *
2550  * @bp:                 driver handle
2551  * @mdc_mdio_access:    access type
2552  * @port:               port id
2553  *
2554  * This function selects the MDC/MDIO access (through emac0 or
2555  * emac1) depend on the mdc_mdio_access, port, port swapped. Each
2556  * phy has a default access mode, which could also be overridden
2557  * by nvram configuration. This parameter, whether this is the
2558  * default phy configuration, or the nvram overrun
2559  * configuration, is passed here as mdc_mdio_access and selects
2560  * the emac_base for the CL45 read/writes operations
2561  */
2562 static uint32_t bnx2x_get_emac_base(struct bnx2x *bp,
2563                                uint32_t mdc_mdio_access, uint8_t port)
2564 {
2565         uint32_t emac_base = 0;
2566         switch (mdc_mdio_access) {
2567         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_PHY_TYPE:
2568                 break;
2569         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC0:
2570                 if (REG_RD(bp, NIG_REG_PORT_SWAP))
2571                         emac_base = GRCBASE_EMAC1;
2572                 else
2573                         emac_base = GRCBASE_EMAC0;
2574                 break;
2575         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1:
2576                 if (REG_RD(bp, NIG_REG_PORT_SWAP))
2577                         emac_base = GRCBASE_EMAC0;
2578                 else
2579                         emac_base = GRCBASE_EMAC1;
2580                 break;
2581         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH:
2582                 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
2583                 break;
2584         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED:
2585                 emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
2586                 break;
2587         default:
2588                 break;
2589         }
2590         return emac_base;
2591
2592 }
2593
2594 /******************************************************************/
2595 /*                      CL22 access functions                     */
2596 /******************************************************************/
2597 static int bnx2x_cl22_write(struct bnx2x *bp,
2598                                        struct bnx2x_phy *phy,
2599                                        uint16_t reg, uint16_t val)
2600 {
2601         uint32_t tmp, mode;
2602         uint8_t i;
2603         int rc = 0;
2604         /* Switch to CL22 */
2605         mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
2606         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE,
2607                mode & ~EMAC_MDIO_MODE_CLAUSE_45);
2608
2609         /* Address */
2610         tmp = ((phy->addr << 21) | (reg << 16) | val |
2611                EMAC_MDIO_COMM_COMMAND_WRITE_22 |
2612                EMAC_MDIO_COMM_START_BUSY);
2613         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
2614
2615         for (i = 0; i < 50; i++) {
2616                 udelay(10);
2617
2618                 tmp = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
2619                 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
2620                         udelay(5);
2621                         break;
2622                 }
2623         }
2624         if (tmp & EMAC_MDIO_COMM_START_BUSY) {
2625                 DP(NETIF_MSG_LINK, "write phy register failed\n");
2626                 rc = -EFAULT;
2627         }
2628         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode);
2629         return rc;
2630 }
2631
2632 static int bnx2x_cl22_read(struct bnx2x *bp,
2633                                       struct bnx2x_phy *phy,
2634                                       uint16_t reg, uint16_t *ret_val)
2635 {
2636         uint32_t val, mode;
2637         uint16_t i;
2638         int rc = 0;
2639
2640         /* Switch to CL22 */
2641         mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
2642         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE,
2643                mode & ~EMAC_MDIO_MODE_CLAUSE_45);
2644
2645         /* Address */
2646         val = ((phy->addr << 21) | (reg << 16) |
2647                EMAC_MDIO_COMM_COMMAND_READ_22 |
2648                EMAC_MDIO_COMM_START_BUSY);
2649         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
2650
2651         for (i = 0; i < 50; i++) {
2652                 udelay(10);
2653
2654                 val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
2655                 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
2656                         *ret_val = (uint16_t)(val & EMAC_MDIO_COMM_DATA);
2657                         udelay(5);
2658                         break;
2659                 }
2660         }
2661         if (val & EMAC_MDIO_COMM_START_BUSY) {
2662                 DP(NETIF_MSG_LINK, "read phy register failed\n");
2663
2664                 *ret_val = 0;
2665                 rc = -EFAULT;
2666         }
2667         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode);
2668         return rc;
2669 }
2670
2671 /******************************************************************/
2672 /*                      CL45 access functions                     */
2673 /******************************************************************/
2674 static int bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy,
2675                            uint8_t devad, uint16_t reg, uint16_t *ret_val)
2676 {
2677         uint32_t val;
2678         uint16_t i;
2679         int rc = 0;
2680         uint32_t chip_id;
2681         if (phy->flags & FLAGS_MDC_MDIO_WA_G) {
2682                 chip_id = (REG_RD(bp, MISC_REG_CHIP_NUM) << 16) |
2683                           ((REG_RD(bp, MISC_REG_CHIP_REV) & 0xf) << 12);
2684                 bnx2x_set_mdio_clk(bp, chip_id, phy->mdio_ctrl);
2685         }
2686
2687         if (phy->flags & FLAGS_MDC_MDIO_WA_B0)
2688                 bnx2x_bits_en(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
2689                               EMAC_MDIO_STATUS_10MB);
2690         /* Address */
2691         val = ((phy->addr << 21) | (devad << 16) | reg |
2692                EMAC_MDIO_COMM_COMMAND_ADDRESS |
2693                EMAC_MDIO_COMM_START_BUSY);
2694         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
2695
2696         for (i = 0; i < 50; i++) {
2697                 udelay(10);
2698
2699                 val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
2700                 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
2701                         udelay(5);
2702                         break;
2703                 }
2704         }
2705         if (val & EMAC_MDIO_COMM_START_BUSY) {
2706                 DP(NETIF_MSG_LINK, "read phy register failed\n");
2707                 netdev_err(bp->dev,  "MDC/MDIO access timeout\n");
2708                 *ret_val = 0;
2709                 rc = -EFAULT;
2710         } else {
2711                 /* Data */
2712                 val = ((phy->addr << 21) | (devad << 16) |
2713                        EMAC_MDIO_COMM_COMMAND_READ_45 |
2714                        EMAC_MDIO_COMM_START_BUSY);
2715                 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
2716
2717                 for (i = 0; i < 50; i++) {
2718                         udelay(10);
2719
2720                         val = REG_RD(bp, phy->mdio_ctrl +
2721                                      EMAC_REG_EMAC_MDIO_COMM);
2722                         if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
2723                                 *ret_val = (uint16_t)(val & EMAC_MDIO_COMM_DATA);
2724                                 break;
2725                         }
2726                 }
2727                 if (val & EMAC_MDIO_COMM_START_BUSY) {
2728                         DP(NETIF_MSG_LINK, "read phy register failed\n");
2729                         netdev_err(bp->dev,  "MDC/MDIO access timeout\n");
2730                         *ret_val = 0;
2731                         rc = -EFAULT;
2732                 }
2733         }
2734         /* Work around for E3 A0 */
2735         if (phy->flags & FLAGS_MDC_MDIO_WA) {
2736                 phy->flags ^= FLAGS_DUMMY_READ;
2737                 if (phy->flags & FLAGS_DUMMY_READ) {
2738                         uint16_t temp_val;
2739                         bnx2x_cl45_read(bp, phy, devad, 0xf, &temp_val);
2740                 }
2741         }
2742
2743         if (phy->flags & FLAGS_MDC_MDIO_WA_B0)
2744                 bnx2x_bits_dis(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
2745                                EMAC_MDIO_STATUS_10MB);
2746         return rc;
2747 }
2748
2749 static int bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,
2750                             uint8_t devad, uint16_t reg, uint16_t val)
2751 {
2752         uint32_t tmp;
2753         uint8_t i;
2754         int rc = 0;
2755         uint32_t chip_id;
2756         if (phy->flags & FLAGS_MDC_MDIO_WA_G) {
2757                 chip_id = (REG_RD(bp, MISC_REG_CHIP_NUM) << 16) |
2758                           ((REG_RD(bp, MISC_REG_CHIP_REV) & 0xf) << 12);
2759                 bnx2x_set_mdio_clk(bp, chip_id, phy->mdio_ctrl);
2760         }
2761
2762         if (phy->flags & FLAGS_MDC_MDIO_WA_B0)
2763                 bnx2x_bits_en(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
2764                               EMAC_MDIO_STATUS_10MB);
2765
2766         /* Address */
2767         tmp = ((phy->addr << 21) | (devad << 16) | reg |
2768                EMAC_MDIO_COMM_COMMAND_ADDRESS |
2769                EMAC_MDIO_COMM_START_BUSY);
2770         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
2771
2772         for (i = 0; i < 50; i++) {
2773                 udelay(10);
2774
2775                 tmp = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
2776                 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
2777                         udelay(5);
2778                         break;
2779                 }
2780         }
2781         if (tmp & EMAC_MDIO_COMM_START_BUSY) {
2782                 DP(NETIF_MSG_LINK, "write phy register failed\n");
2783                 netdev_err(bp->dev,  "MDC/MDIO access timeout\n");
2784                 rc = -EFAULT;
2785         } else {
2786                 /* Data */
2787                 tmp = ((phy->addr << 21) | (devad << 16) | val |
2788                        EMAC_MDIO_COMM_COMMAND_WRITE_45 |
2789                        EMAC_MDIO_COMM_START_BUSY);
2790                 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
2791
2792                 for (i = 0; i < 50; i++) {
2793                         udelay(10);
2794
2795                         tmp = REG_RD(bp, phy->mdio_ctrl +
2796                                      EMAC_REG_EMAC_MDIO_COMM);
2797                         if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
2798                                 udelay(5);
2799                                 break;
2800                         }
2801                 }
2802                 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
2803                         DP(NETIF_MSG_LINK, "write phy register failed\n");
2804                         netdev_err(bp->dev,  "MDC/MDIO access timeout\n");
2805                         rc = -EFAULT;
2806                 }
2807         }
2808         /* Work around for E3 A0 */
2809         if (phy->flags & FLAGS_MDC_MDIO_WA) {
2810                 phy->flags ^= FLAGS_DUMMY_READ;
2811                 if (phy->flags & FLAGS_DUMMY_READ) {
2812                         uint16_t temp_val;
2813                         bnx2x_cl45_read(bp, phy, devad, 0xf, &temp_val);
2814                 }
2815         }
2816         if (phy->flags & FLAGS_MDC_MDIO_WA_B0)
2817                 bnx2x_bits_dis(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
2818                                EMAC_MDIO_STATUS_10MB);
2819         return rc;
2820 }
2821
2822 /******************************************************************/
2823 /*                      EEE section                                */
2824 /******************************************************************/
2825 static uint8_t bnx2x_eee_has_cap(struct link_params *params)
2826 {
2827         struct bnx2x *bp = params->bp;
2828
2829         if (REG_RD(bp, params->shmem2_base) <=
2830                    offsetof(struct shmem2_region, eee_status[params->port]))
2831                 return 0;
2832
2833         return 1;
2834 }
2835
2836 static int bnx2x_eee_nvram_to_time(uint32_t nvram_mode, uint32_t *idle_timer)
2837 {
2838         switch (nvram_mode) {
2839         case PORT_FEAT_CFG_EEE_POWER_MODE_BALANCED:
2840                 *idle_timer = EEE_MODE_NVRAM_BALANCED_TIME;
2841                 break;
2842         case PORT_FEAT_CFG_EEE_POWER_MODE_AGGRESSIVE:
2843                 *idle_timer = EEE_MODE_NVRAM_AGGRESSIVE_TIME;
2844                 break;
2845         case PORT_FEAT_CFG_EEE_POWER_MODE_LOW_LATENCY:
2846                 *idle_timer = EEE_MODE_NVRAM_LATENCY_TIME;
2847                 break;
2848         default:
2849                 *idle_timer = 0;
2850                 break;
2851         }
2852
2853         return 0;
2854 }
2855
2856 static int bnx2x_eee_time_to_nvram(uint32_t idle_timer, uint32_t *nvram_mode)
2857 {
2858         switch (idle_timer) {
2859         case EEE_MODE_NVRAM_BALANCED_TIME:
2860                 *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_BALANCED;
2861                 break;
2862         case EEE_MODE_NVRAM_AGGRESSIVE_TIME:
2863                 *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_AGGRESSIVE;
2864                 break;
2865         case EEE_MODE_NVRAM_LATENCY_TIME:
2866                 *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_LOW_LATENCY;
2867                 break;
2868         default:
2869                 *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_DISABLED;
2870                 break;
2871         }
2872
2873         return 0;
2874 }
2875
2876 static uint32_t bnx2x_eee_calc_timer(struct link_params *params)
2877 {
2878         uint32_t eee_mode, eee_idle;
2879         struct bnx2x *bp = params->bp;
2880
2881         if (params->eee_mode & EEE_MODE_OVERRIDE_NVRAM) {
2882                 if (params->eee_mode & EEE_MODE_OUTPUT_TIME) {
2883                         /* time value in eee_mode --> used directly*/
2884                         eee_idle = params->eee_mode & EEE_MODE_TIMER_MASK;
2885                 } else {
2886                         /* hsi value in eee_mode --> time */
2887                         if (bnx2x_eee_nvram_to_time(params->eee_mode &
2888                                                     EEE_MODE_NVRAM_MASK,
2889                                                     &eee_idle))
2890                                 return 0;
2891                 }
2892         } else {
2893                 /* hsi values in nvram --> time*/
2894                 eee_mode = ((REG_RD(bp, params->shmem_base +
2895                                     offsetof(struct shmem_region, dev_info.
2896                                     port_feature_config[params->port].
2897                                     eee_power_mode)) &
2898                              PORT_FEAT_CFG_EEE_POWER_MODE_MASK) >>
2899                             PORT_FEAT_CFG_EEE_POWER_MODE_SHIFT);
2900
2901                 if (bnx2x_eee_nvram_to_time(eee_mode, &eee_idle))
2902                         return 0;
2903         }
2904
2905         return eee_idle;
2906 }
2907
2908 static int bnx2x_eee_set_timers(struct link_params *params,
2909                                    struct link_vars *vars)
2910 {
2911         uint32_t eee_idle = 0, eee_mode;
2912         struct bnx2x *bp = params->bp;
2913
2914         eee_idle = bnx2x_eee_calc_timer(params);
2915
2916         if (eee_idle) {
2917                 REG_WR(bp, MISC_REG_CPMU_LP_IDLE_THR_P0 + (params->port << 2),
2918                        eee_idle);
2919         } else if ((params->eee_mode & EEE_MODE_ENABLE_LPI) &&
2920                    (params->eee_mode & EEE_MODE_OVERRIDE_NVRAM) &&
2921                    (params->eee_mode & EEE_MODE_OUTPUT_TIME)) {
2922                 DP(NETIF_MSG_LINK, "Error: Tx LPI is enabled with timer 0\n");
2923                 return -EINVAL;
2924         }
2925
2926         vars->eee_status &= ~(SHMEM_EEE_TIMER_MASK | SHMEM_EEE_TIME_OUTPUT_BIT);
2927         if (params->eee_mode & EEE_MODE_OUTPUT_TIME) {
2928                 /* eee_idle in 1u --> eee_status in 16u */
2929                 eee_idle >>= 4;
2930                 vars->eee_status |= (eee_idle & SHMEM_EEE_TIMER_MASK) |
2931                                     SHMEM_EEE_TIME_OUTPUT_BIT;
2932         } else {
2933                 if (bnx2x_eee_time_to_nvram(eee_idle, &eee_mode))
2934                         return -EINVAL;
2935                 vars->eee_status |= eee_mode;
2936         }
2937
2938         return 0;
2939 }
2940
2941 static int bnx2x_eee_initial_config(struct link_params *params,
2942                                      struct link_vars *vars, uint8_t mode)
2943 {
2944         vars->eee_status |= ((uint32_t) mode) << SHMEM_EEE_SUPPORTED_SHIFT;
2945
2946         /* Propogate params' bits --> vars (for migration exposure) */
2947         if (params->eee_mode & EEE_MODE_ENABLE_LPI)
2948                 vars->eee_status |= SHMEM_EEE_LPI_REQUESTED_BIT;
2949         else
2950                 vars->eee_status &= ~SHMEM_EEE_LPI_REQUESTED_BIT;
2951
2952         if (params->eee_mode & EEE_MODE_ADV_LPI)
2953                 vars->eee_status |= SHMEM_EEE_REQUESTED_BIT;
2954         else
2955                 vars->eee_status &= ~SHMEM_EEE_REQUESTED_BIT;
2956
2957         return bnx2x_eee_set_timers(params, vars);
2958 }
2959
2960 static int bnx2x_eee_disable(struct bnx2x_phy *phy,
2961                                 struct link_params *params,
2962                                 struct link_vars *vars)
2963 {
2964         struct bnx2x *bp = params->bp;
2965
2966         /* Make Certain LPI is disabled */
2967         REG_WR(bp, MISC_REG_CPMU_LP_FW_ENABLE_P0 + (params->port << 2), 0);
2968
2969         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_EEE_ADV, 0x0);
2970
2971         vars->eee_status &= ~SHMEM_EEE_ADV_STATUS_MASK;
2972
2973         return 0;
2974 }
2975
2976 static int bnx2x_eee_advertise(struct bnx2x_phy *phy,
2977                                   struct link_params *params,
2978                                   struct link_vars *vars, uint8_t modes)
2979 {
2980         struct bnx2x *bp = params->bp;
2981         uint16_t val = 0;
2982
2983         /* Mask events preventing LPI generation */
2984         REG_WR(bp, MISC_REG_CPMU_LP_MASK_EXT_P0 + (params->port << 2), 0xfc20);
2985
2986         if (modes & SHMEM_EEE_10G_ADV) {
2987                 DP(NETIF_MSG_LINK, "Advertise 10GBase-T EEE\n");
2988                 val |= 0x8;
2989         }
2990         if (modes & SHMEM_EEE_1G_ADV) {
2991                 DP(NETIF_MSG_LINK, "Advertise 1GBase-T EEE\n");
2992                 val |= 0x4;
2993         }
2994
2995         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_EEE_ADV, val);
2996
2997         vars->eee_status &= ~SHMEM_EEE_ADV_STATUS_MASK;
2998         vars->eee_status |= (modes << SHMEM_EEE_ADV_STATUS_SHIFT);
2999
3000         return 0;
3001 }
3002
3003 static void bnx2x_update_mng_eee(struct link_params *params,
3004                                  uint32_t eee_status)
3005 {
3006         struct bnx2x *bp = params->bp;
3007
3008         if (bnx2x_eee_has_cap(params))
3009                 REG_WR(bp, params->shmem2_base +
3010                        offsetof(struct shmem2_region,
3011                                 eee_status[params->port]), eee_status);
3012 }
3013
3014 static void bnx2x_eee_an_resolve(struct bnx2x_phy *phy,
3015                                   struct link_params *params,
3016                                   struct link_vars *vars)
3017 {
3018         struct bnx2x *bp = params->bp;
3019         uint16_t adv = 0, lp = 0;
3020         uint32_t lp_adv = 0;
3021         uint8_t neg = 0;
3022
3023         bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_EEE_ADV, &adv);
3024         bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_LP_EEE_ADV, &lp);
3025
3026         if (lp & 0x2) {
3027                 lp_adv |= SHMEM_EEE_100M_ADV;
3028                 if (adv & 0x2) {
3029                         if (vars->line_speed == SPEED_100)
3030                                 neg = 1;
3031                         DP(NETIF_MSG_LINK, "EEE negotiated - 100M\n");
3032                 }
3033         }
3034         if (lp & 0x14) {
3035                 lp_adv |= SHMEM_EEE_1G_ADV;
3036                 if (adv & 0x14) {
3037                         if (vars->line_speed == SPEED_1000)
3038                                 neg = 1;
3039                         DP(NETIF_MSG_LINK, "EEE negotiated - 1G\n");
3040                 }
3041         }
3042         if (lp & 0x68) {
3043                 lp_adv |= SHMEM_EEE_10G_ADV;
3044                 if (adv & 0x68) {
3045                         if (vars->line_speed == SPEED_10000)
3046                                 neg = 1;
3047                         DP(NETIF_MSG_LINK, "EEE negotiated - 10G\n");
3048                 }
3049         }
3050
3051         vars->eee_status &= ~SHMEM_EEE_LP_ADV_STATUS_MASK;
3052         vars->eee_status |= (lp_adv << SHMEM_EEE_LP_ADV_STATUS_SHIFT);
3053
3054         if (neg) {
3055                 DP(NETIF_MSG_LINK, "EEE is active\n");
3056                 vars->eee_status |= SHMEM_EEE_ACTIVE_BIT;
3057         }
3058
3059 }
3060
3061 /******************************************************************/
3062 /*                      BSC access functions from E3              */
3063 /******************************************************************/
3064 static void bnx2x_bsc_module_sel(struct link_params *params)
3065 {
3066         int idx;
3067         uint32_t board_cfg, sfp_ctrl;
3068         uint32_t i2c_pins[I2C_SWITCH_WIDTH], i2c_val[I2C_SWITCH_WIDTH];
3069         struct bnx2x *bp = params->bp;
3070         uint8_t port = params->port;
3071         /* Read I2C output PINs */
3072         board_cfg = REG_RD(bp, params->shmem_base +
3073                            offsetof(struct shmem_region,
3074                                     dev_info.shared_hw_config.board));
3075         i2c_pins[I2C_BSC0] = board_cfg & SHARED_HW_CFG_E3_I2C_MUX0_MASK;
3076         i2c_pins[I2C_BSC1] = (board_cfg & SHARED_HW_CFG_E3_I2C_MUX1_MASK) >>
3077                         SHARED_HW_CFG_E3_I2C_MUX1_SHIFT;
3078
3079         /* Read I2C output value */
3080         sfp_ctrl = REG_RD(bp, params->shmem_base +
3081                           offsetof(struct shmem_region,
3082                                  dev_info.port_hw_config[port].e3_cmn_pin_cfg));
3083         i2c_val[I2C_BSC0] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX0_MASK) > 0;
3084         i2c_val[I2C_BSC1] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX1_MASK) > 0;
3085         DP(NETIF_MSG_LINK, "Setting BSC switch\n");
3086         for (idx = 0; idx < I2C_SWITCH_WIDTH; idx++)
3087                 bnx2x_set_cfg_pin(bp, i2c_pins[idx], i2c_val[idx]);
3088 }
3089
3090 static int bnx2x_bsc_read(struct link_params *params,
3091                           struct bnx2x *bp,
3092                           uint8_t sl_devid,
3093                           uint16_t sl_addr,
3094                           uint8_t lc_addr,
3095                           uint8_t xfer_cnt,
3096                           uint32_t *data_array)
3097 {
3098         uint32_t val, i;
3099         int rc = 0;
3100
3101         if (xfer_cnt > 16) {
3102                 DP(NETIF_MSG_LINK, "invalid xfer_cnt %d. Max is 16 bytes\n",
3103                                         xfer_cnt);
3104                 return -EINVAL;
3105         }
3106         bnx2x_bsc_module_sel(params);
3107
3108         xfer_cnt = 16 - lc_addr;
3109
3110         /* Enable the engine */
3111         val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
3112         val |= MCPR_IMC_COMMAND_ENABLE;
3113         REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val);
3114
3115         /* Program slave device ID */
3116         val = (sl_devid << 16) | sl_addr;
3117         REG_WR(bp, MCP_REG_MCPR_IMC_SLAVE_CONTROL, val);
3118
3119         /* Start xfer with 0 byte to update the address pointer ???*/
3120         val = (MCPR_IMC_COMMAND_ENABLE) |
3121               (MCPR_IMC_COMMAND_WRITE_OP <<
3122                 MCPR_IMC_COMMAND_OPERATION_BITSHIFT) |
3123                 (lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) | (0);
3124         REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val);
3125
3126         /* Poll for completion */
3127         i = 0;
3128         val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
3129         while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) {
3130                 udelay(10);
3131                 val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
3132                 if (i++ > 1000) {
3133                         DP(NETIF_MSG_LINK, "wr 0 byte timed out after %d try\n",
3134                                                                 i);
3135                         rc = -EFAULT;
3136                         break;
3137                 }
3138         }
3139         if (rc == -EFAULT)
3140                 return rc;
3141
3142         /* Start xfer with read op */
3143         val = (MCPR_IMC_COMMAND_ENABLE) |
3144                 (MCPR_IMC_COMMAND_READ_OP <<
3145                 MCPR_IMC_COMMAND_OPERATION_BITSHIFT) |
3146                 (lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) |
3147                   (xfer_cnt);
3148         REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val);
3149
3150         /* Poll for completion */
3151         i = 0;
3152         val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
3153         while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) {
3154                 udelay(10);
3155                 val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
3156                 if (i++ > 1000) {
3157                         DP(NETIF_MSG_LINK, "rd op timed out after %d try\n", i);
3158                         rc = -EFAULT;
3159                         break;
3160                 }
3161         }
3162         if (rc == -EFAULT)
3163                 return rc;
3164
3165         for (i = (lc_addr >> 2); i < 4; i++) {
3166                 data_array[i] = REG_RD(bp, (MCP_REG_MCPR_IMC_DATAREG0 + i*4));
3167 #ifdef __BIG_ENDIAN
3168                 data_array[i] = ((data_array[i] & 0x000000ff) << 24) |
3169                                 ((data_array[i] & 0x0000ff00) << 8) |
3170                                 ((data_array[i] & 0x00ff0000) >> 8) |
3171                                 ((data_array[i] & 0xff000000) >> 24);
3172 #endif
3173         }
3174         return rc;
3175 }
3176
3177 static void bnx2x_cl45_read_or_write(struct bnx2x *bp, struct bnx2x_phy *phy,
3178                                      uint8_t devad, uint16_t reg,
3179                                      uint16_t or_val)
3180 {
3181         uint16_t val;
3182         bnx2x_cl45_read(bp, phy, devad, reg, &val);
3183         bnx2x_cl45_write(bp, phy, devad, reg, val | or_val);
3184 }
3185
3186 static void bnx2x_cl45_read_and_write(struct bnx2x *bp,
3187                                       struct bnx2x_phy *phy,
3188                                       uint8_t devad, uint16_t reg,
3189                                       uint16_t and_val)
3190 {
3191         uint16_t val;
3192         bnx2x_cl45_read(bp, phy, devad, reg, &val);
3193         bnx2x_cl45_write(bp, phy, devad, reg, val & and_val);
3194 }
3195
3196 int bnx2x_phy_read(struct link_params *params, uint8_t phy_addr,
3197                    uint8_t devad, uint16_t reg, uint16_t *ret_val)
3198 {
3199         uint8_t phy_index;
3200         /* Probe for the phy according to the given phy_addr, and execute
3201          * the read request on it
3202          */
3203         for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
3204                 if (params->phy[phy_index].addr == phy_addr) {
3205                         return bnx2x_cl45_read(params->bp,
3206                                                &params->phy[phy_index], devad,
3207                                                reg, ret_val);
3208                 }
3209         }
3210         return -EINVAL;
3211 }
3212
3213 int bnx2x_phy_write(struct link_params *params, uint8_t phy_addr,
3214                     uint8_t devad, uint16_t reg, uint16_t val)
3215 {
3216         uint8_t phy_index;
3217         /* Probe for the phy according to the given phy_addr, and execute
3218          * the write request on it
3219          */
3220         for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
3221                 if (params->phy[phy_index].addr == phy_addr) {
3222                         return bnx2x_cl45_write(params->bp,
3223                                                 &params->phy[phy_index], devad,
3224                                                 reg, val);
3225                 }
3226         }
3227         return -EINVAL;
3228 }
3229 static uint8_t bnx2x_get_warpcore_lane(struct bnx2x_phy *phy,
3230                                   struct link_params *params)
3231 {
3232         uint8_t lane = 0;
3233         struct bnx2x *bp = params->bp;
3234         uint32_t path_swap, path_swap_ovr;
3235         uint8_t path, port;
3236
3237         path = BP_PATH(bp);
3238         port = params->port;
3239
3240         if (bnx2x_is_4_port_mode(bp)) {
3241                 uint32_t port_swap, port_swap_ovr;
3242
3243                 /* Figure out path swap value */
3244                 path_swap_ovr = REG_RD(bp, MISC_REG_FOUR_PORT_PATH_SWAP_OVWR);
3245                 if (path_swap_ovr & 0x1)
3246                         path_swap = (path_swap_ovr & 0x2);
3247                 else
3248                         path_swap = REG_RD(bp, MISC_REG_FOUR_PORT_PATH_SWAP);
3249
3250                 if (path_swap)
3251                         path = path ^ 1;
3252
3253                 /* Figure out port swap value */
3254                 port_swap_ovr = REG_RD(bp, MISC_REG_FOUR_PORT_PORT_SWAP_OVWR);
3255                 if (port_swap_ovr & 0x1)
3256                         port_swap = (port_swap_ovr & 0x2);
3257                 else
3258                         port_swap = REG_RD(bp, MISC_REG_FOUR_PORT_PORT_SWAP);
3259
3260                 if (port_swap)
3261                         port = port ^ 1;
3262
3263                 lane = (port<<1) + path;
3264         } else { /* Two port mode - no port swap */
3265
3266                 /* Figure out path swap value */
3267                 path_swap_ovr =
3268                         REG_RD(bp, MISC_REG_TWO_PORT_PATH_SWAP_OVWR);
3269                 if (path_swap_ovr & 0x1) {
3270                         path_swap = (path_swap_ovr & 0x2);
3271                 } else {
3272                         path_swap =
3273                                 REG_RD(bp, MISC_REG_TWO_PORT_PATH_SWAP);
3274                 }
3275                 if (path_swap)
3276                         path = path ^ 1;
3277
3278                 lane = path << 1 ;
3279         }
3280         return lane;
3281 }
3282
3283 static void bnx2x_set_aer_mmd(struct link_params *params,
3284                               struct bnx2x_phy *phy)
3285 {
3286         uint32_t ser_lane;
3287         uint16_t offset, aer_val;
3288         struct bnx2x *bp = params->bp;
3289         ser_lane = ((params->lane_config &
3290                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
3291                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
3292
3293         offset = (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ?
3294                 (phy->addr + ser_lane) : 0;
3295
3296         if (USES_WARPCORE(bp)) {
3297                 aer_val = bnx2x_get_warpcore_lane(phy, params);
3298                 /* In Dual-lane mode, two lanes are joined together,
3299                  * so in order to configure them, the AER broadcast method is
3300                  * used here.
3301                  * 0x200 is the broadcast address for lanes 0,1
3302                  * 0x201 is the broadcast address for lanes 2,3
3303                  */
3304                 if (phy->flags & FLAGS_WC_DUAL_MODE)
3305                         aer_val = (aer_val >> 1) | 0x200;
3306         } else if (CHIP_IS_E2(bp))
3307                 aer_val = 0x3800 + offset - 1;
3308         else
3309                 aer_val = 0x3800 + offset;
3310
3311         CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
3312                           MDIO_AER_BLOCK_AER_REG, aer_val);
3313
3314 }
3315
3316 /******************************************************************/
3317 /*                      Internal phy section                      */
3318 /******************************************************************/
3319
3320 static void bnx2x_set_serdes_access(struct bnx2x *bp, uint8_t port)
3321 {
3322         uint32_t emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
3323
3324         /* Set Clause 22 */
3325         REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 1);
3326         REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
3327         udelay(500);
3328         REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
3329         udelay(500);
3330          /* Set Clause 45 */
3331         REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 0);
3332 }
3333
3334 static void bnx2x_serdes_deassert(struct bnx2x *bp, uint8_t port)
3335 {
3336         uint32_t val;
3337
3338         DP(NETIF_MSG_LINK, "bnx2x_serdes_deassert\n");
3339
3340         val = SERDES_RESET_BITS << (port*16);
3341
3342         /* Reset and unreset the SerDes/XGXS */
3343         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
3344         udelay(500);
3345         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
3346
3347         bnx2x_set_serdes_access(bp, port);
3348
3349         REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD + port*0x10,
3350                DEFAULT_PHY_DEV_ADDR);
3351 }
3352
3353 static void bnx2x_xgxs_specific_func(struct bnx2x_phy *phy,
3354                                      struct link_params *params,
3355                                      uint32_t action)
3356 {
3357         struct bnx2x *bp = params->bp;
3358         switch (action) {
3359         case PHY_INIT:
3360                 /* Set correct devad */
3361                 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + params->port*0x18, 0);
3362                 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
3363                        phy->def_md_devad);
3364                 break;
3365         }
3366 }
3367
3368 static void bnx2x_xgxs_deassert(struct link_params *params)
3369 {
3370         struct bnx2x *bp = params->bp;
3371         uint8_t port;
3372         uint32_t val;
3373         DP(NETIF_MSG_LINK, "bnx2x_xgxs_deassert\n");
3374         port = params->port;
3375
3376         val = XGXS_RESET_BITS << (port*16);
3377
3378         /* Reset and unreset the SerDes/XGXS */
3379         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
3380         udelay(500);
3381         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
3382         bnx2x_xgxs_specific_func(&params->phy[INT_PHY], params,
3383                                  PHY_INIT);
3384 }
3385
3386 static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy,
3387                                      struct link_params *params,
3388                                      uint16_t *ieee_fc)
3389 {
3390         struct bnx2x *bp = params->bp;
3391         *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
3392         /* Resolve pause mode and advertisement Please refer to Table
3393          * 28B-3 of the 802.3ab-1999 spec
3394          */
3395
3396         switch (phy->req_flow_ctrl) {
3397         case BNX2X_FLOW_CTRL_AUTO:
3398                 switch (params->req_fc_auto_adv) {
3399                 case BNX2X_FLOW_CTRL_BOTH:
3400                         *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
3401                         break;
3402                 case BNX2X_FLOW_CTRL_RX:
3403                 case BNX2X_FLOW_CTRL_TX:
3404                         *ieee_fc |=
3405                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
3406                         break;
3407                 default:
3408                         break;
3409                 }
3410                 break;
3411         case BNX2X_FLOW_CTRL_TX:
3412                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
3413                 break;
3414
3415         case BNX2X_FLOW_CTRL_RX:
3416         case BNX2X_FLOW_CTRL_BOTH:
3417                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
3418                 break;
3419
3420         case BNX2X_FLOW_CTRL_NONE:
3421         default:
3422                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
3423                 break;
3424         }
3425         DP(NETIF_MSG_LINK, "ieee_fc = 0x%x\n", *ieee_fc);
3426 }
3427
3428 static void set_phy_vars(struct link_params *params,
3429                          struct link_vars *vars)
3430 {
3431         struct bnx2x *bp = params->bp;
3432         uint8_t actual_phy_idx, phy_index, link_cfg_idx;
3433         uint8_t phy_config_swapped = params->multi_phy_config &
3434                         PORT_HW_CFG_PHY_SWAPPED_ENABLED;
3435         for (phy_index = INT_PHY; phy_index < params->num_phys;
3436               phy_index++) {
3437                 link_cfg_idx = LINK_CONFIG_IDX(phy_index);
3438                 actual_phy_idx = phy_index;
3439                 if (phy_config_swapped) {
3440                         if (phy_index == EXT_PHY1)
3441                                 actual_phy_idx = EXT_PHY2;
3442                         else if (phy_index == EXT_PHY2)
3443                                 actual_phy_idx = EXT_PHY1;
3444                 }
3445                 params->phy[actual_phy_idx].req_flow_ctrl =
3446                         params->req_flow_ctrl[link_cfg_idx];
3447
3448                 params->phy[actual_phy_idx].req_line_speed =
3449                         params->req_line_speed[link_cfg_idx];
3450
3451                 params->phy[actual_phy_idx].speed_cap_mask =
3452                         params->speed_cap_mask[link_cfg_idx];
3453
3454                 params->phy[actual_phy_idx].req_duplex =
3455                         params->req_duplex[link_cfg_idx];
3456
3457                 if (params->req_line_speed[link_cfg_idx] ==
3458                     SPEED_AUTO_NEG)
3459                         vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
3460
3461                 DP(NETIF_MSG_LINK, "req_flow_ctrl %x, req_line_speed %x,"
3462                            " speed_cap_mask %x\n",
3463                            params->phy[actual_phy_idx].req_flow_ctrl,
3464                            params->phy[actual_phy_idx].req_line_speed,
3465                            params->phy[actual_phy_idx].speed_cap_mask);
3466         }
3467 }
3468
3469 static void bnx2x_ext_phy_set_pause(struct link_params *params,
3470                                     struct bnx2x_phy *phy,
3471                                     struct link_vars *vars)
3472 {
3473         uint16_t val;
3474         struct bnx2x *bp = params->bp;
3475         /* Read modify write pause advertizing */
3476         bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, &val);
3477
3478         val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
3479
3480         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
3481         bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
3482         if ((vars->ieee_fc &
3483             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
3484             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
3485                 val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
3486         }
3487         if ((vars->ieee_fc &
3488             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
3489             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
3490                 val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
3491         }
3492         DP(NETIF_MSG_LINK, "Ext phy AN advertize 0x%x\n", val);
3493         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, val);
3494 }
3495
3496 static void bnx2x_pause_resolve(struct link_vars *vars, uint32_t pause_result)
3497 {                                               /*  LD      LP   */
3498         switch (pause_result) {                 /* ASYM P ASYM P */
3499         case 0xb:                               /*   1  0   1  1 */
3500                 vars->flow_ctrl = BNX2X_FLOW_CTRL_TX;
3501                 break;
3502
3503         case 0xe:                               /*   1  1   1  0 */
3504                 vars->flow_ctrl = BNX2X_FLOW_CTRL_RX;
3505                 break;
3506
3507         case 0x5:                               /*   0  1   0  1 */
3508         case 0x7:                               /*   0  1   1  1 */
3509         case 0xd:                               /*   1  1   0  1 */
3510         case 0xf:                               /*   1  1   1  1 */
3511                 vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
3512                 break;
3513
3514         default:
3515                 break;
3516         }
3517         if (pause_result & (1<<0))
3518                 vars->link_status |= LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE;
3519         if (pause_result & (1<<1))
3520                 vars->link_status |= LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE;
3521
3522 }
3523
3524 static void bnx2x_ext_phy_update_adv_fc(struct bnx2x_phy *phy,
3525                                         struct link_params *params,
3526                                         struct link_vars *vars)
3527 {
3528         uint16_t ld_pause;              /* local */
3529         uint16_t lp_pause;              /* link partner */
3530         uint16_t pause_result;
3531         struct bnx2x *bp = params->bp;
3532         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) {
3533                 bnx2x_cl22_read(bp, phy, 0x4, &ld_pause);
3534                 bnx2x_cl22_read(bp, phy, 0x5, &lp_pause);
3535         } else if (CHIP_IS_E3(bp) &&
3536                 SINGLE_MEDIA_DIRECT(params)) {
3537                 uint8_t lane = bnx2x_get_warpcore_lane(phy, params);
3538                 uint16_t gp_status, gp_mask;
3539                 bnx2x_cl45_read(bp, phy,
3540                                 MDIO_AN_DEVAD, MDIO_WC_REG_GP2_STATUS_GP_2_4,
3541                                 &gp_status);
3542                 gp_mask = (MDIO_WC_REG_GP2_STATUS_GP_2_4_CL73_AN_CMPL |
3543                            MDIO_WC_REG_GP2_STATUS_GP_2_4_CL37_LP_AN_CAP) <<
3544                         lane;
3545                 if ((gp_status & gp_mask) == gp_mask) {
3546                         bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
3547                                         MDIO_AN_REG_ADV_PAUSE, &ld_pause);
3548                         bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
3549                                         MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
3550                 } else {
3551                         bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
3552                                         MDIO_AN_REG_CL37_FC_LD, &ld_pause);
3553                         bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
3554                                         MDIO_AN_REG_CL37_FC_LP, &lp_pause);
3555                         ld_pause = ((ld_pause &
3556                                      MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH)
3557                                     << 3);
3558                         lp_pause = ((lp_pause &
3559                                      MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH)
3560                                     << 3);
3561                 }
3562         } else {
3563                 bnx2x_cl45_read(bp, phy,
3564                                 MDIO_AN_DEVAD,
3565                                 MDIO_AN_REG_ADV_PAUSE, &ld_pause);
3566                 bnx2x_cl45_read(bp, phy,
3567                                 MDIO_AN_DEVAD,
3568                                 MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
3569         }
3570         pause_result = (ld_pause &
3571                         MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
3572         pause_result |= (lp_pause &
3573                          MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
3574         DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n", pause_result);
3575         bnx2x_pause_resolve(vars, pause_result);
3576
3577 }
3578
3579 static uint8_t bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy,