aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2x/bnx2x_link.c
diff options
context:
space:
mode:
authorVladislav Zolotarov <vladz@broadcom.com>2010-12-13 00:44:25 -0500
committerDavid S. Miller <davem@davemloft.net>2010-12-16 16:15:55 -0500
commitbcab15c5d780bafb38311f00fcb263d03d2b00f1 (patch)
treec50e4971d9c0d071b65dc4c849828d46140fb3a9 /drivers/net/bnx2x/bnx2x_link.c
parente4901dde12d92b70dd13fa8b3bbc9df7a6129aab (diff)
bnx2x: Add DCB/PFC support - link layer
Add appropriate HW DCB/PFC configuration Signed-off-by: Dmitry Kravkov <dmitry@broadcom.com> Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2x/bnx2x_link.c')
-rw-r--r--drivers/net/bnx2x/bnx2x_link.c665
1 files changed, 626 insertions, 39 deletions
diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c
index 38aeffef2a83..97cbee2927fc 100644
--- a/drivers/net/bnx2x/bnx2x_link.c
+++ b/drivers/net/bnx2x/bnx2x_link.c
@@ -164,7 +164,8 @@
164#define EDC_MODE_PASSIVE_DAC 0x0055 164#define EDC_MODE_PASSIVE_DAC 0x0055
165 165
166 166
167 167#define ETS_BW_LIMIT_CREDIT_UPPER_BOUND (0x5000)
168#define ETS_BW_LIMIT_CREDIT_WEIGHT (0x5000)
168/**********************************************************/ 169/**********************************************************/
169/* INTERFACE */ 170/* INTERFACE */
170/**********************************************************/ 171/**********************************************************/
@@ -205,6 +206,273 @@ static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
205 return val; 206 return val;
206} 207}
207 208
209/******************************************************************/
210/* ETS section */
211/******************************************************************/
212void bnx2x_ets_disabled(struct link_params *params)
213{
214 /* ETS disabled configuration*/
215 struct bnx2x *bp = params->bp;
216
217 DP(NETIF_MSG_LINK, "ETS disabled configuration\n");
218
219 /**
220 * mapping between entry priority to client number (0,1,2 -debug and
221 * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
222 * 3bits client num.
223 * PRI4 | PRI3 | PRI2 | PRI1 | PRI0
224 * cos1-100 cos0-011 dbg1-010 dbg0-001 MCP-000
225 */
226
227 REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, 0x4688);
228 /**
229 * Bitmap of 5bits length. Each bit specifies whether the entry behaves
230 * as strict. Bits 0,1,2 - debug and management entries, 3 -
231 * COS0 entry, 4 - COS1 entry.
232 * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
233 * bit4 bit3 bit2 bit1 bit0
234 * MCP and debug are strict
235 */
236
237 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
238 /* defines which entries (clients) are subjected to WFQ arbitration */
239 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0);
240 /**
241 * For strict priority entries defines the number of consecutive
242 * slots for the highest priority.
243 */
244 REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
245 /**
246 * mapping between the CREDIT_WEIGHT registers and actual client
247 * numbers
248 */
249 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0);
250 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0);
251 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0);
252
253 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, 0);
254 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, 0);
255 REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, 0);
256 /* ETS mode disable */
257 REG_WR(bp, PBF_REG_ETS_ENABLED, 0);
258 /**
259 * If ETS mode is enabled (there is no strict priority) defines a WFQ
260 * weight for COS0/COS1.
261 */
262 REG_WR(bp, PBF_REG_COS0_WEIGHT, 0x2710);
263 REG_WR(bp, PBF_REG_COS1_WEIGHT, 0x2710);
264 /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter */
265 REG_WR(bp, PBF_REG_COS0_UPPER_BOUND, 0x989680);
266 REG_WR(bp, PBF_REG_COS1_UPPER_BOUND, 0x989680);
267 /* Defines the number of consecutive slots for the strict priority */
268 REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
269}
270
271void bnx2x_ets_bw_limit_common(const struct link_params *params)
272{
273 /* ETS disabled configuration */
274 struct bnx2x *bp = params->bp;
275 DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n");
276 /**
277 * defines which entries (clients) are subjected to WFQ arbitration
278 * COS0 0x8
279 * COS1 0x10
280 */
281 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0x18);
282 /**
283 * mapping between the ARB_CREDIT_WEIGHT registers and actual
284 * client numbers (WEIGHT_0 does not actually have to represent
285 * client 0)
286 * PRI4 | PRI3 | PRI2 | PRI1 | PRI0
287 * cos1-001 cos0-000 dbg1-100 dbg0-011 MCP-010
288 */
289 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0x111A);
290
291 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0,
292 ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
293 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1,
294 ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
295
296 /* ETS mode enabled*/
297 REG_WR(bp, PBF_REG_ETS_ENABLED, 1);
298
299 /* Defines the number of consecutive slots for the strict priority */
300 REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
301 /**
302 * Bitmap of 5bits length. Each bit specifies whether the entry behaves
303 * as strict. Bits 0,1,2 - debug and management entries, 3 - COS0
304 * entry, 4 - COS1 entry.
305 * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
306 * bit4 bit3 bit2 bit1 bit0
307 * MCP and debug are strict
308 */
309 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
310
311 /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter.*/
312 REG_WR(bp, PBF_REG_COS0_UPPER_BOUND,
313 ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
314 REG_WR(bp, PBF_REG_COS1_UPPER_BOUND,
315 ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
316}
317
318void bnx2x_ets_bw_limit(const struct link_params *params, const u32 cos0_bw,
319 const u32 cos1_bw)
320{
321 /* ETS disabled configuration*/
322 struct bnx2x *bp = params->bp;
323 const u32 total_bw = cos0_bw + cos1_bw;
324 u32 cos0_credit_weight = 0;
325 u32 cos1_credit_weight = 0;
326
327 DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n");
328
329 if ((0 == total_bw) ||
330 (0 == cos0_bw) ||
331 (0 == cos1_bw)) {
332 DP(NETIF_MSG_LINK,
333 "bnx2x_ets_bw_limit: Total BW can't be zero\n");
334 return;
335 }
336
337 cos0_credit_weight = (cos0_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/
338 total_bw;
339 cos1_credit_weight = (cos1_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/
340 total_bw;
341
342 bnx2x_ets_bw_limit_common(params);
343
344 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, cos0_credit_weight);
345 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, cos1_credit_weight);
346
347 REG_WR(bp, PBF_REG_COS0_WEIGHT, cos0_credit_weight);
348 REG_WR(bp, PBF_REG_COS1_WEIGHT, cos1_credit_weight);
349}
350
351u8 bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos)
352{
353 /* ETS disabled configuration*/
354 struct bnx2x *bp = params->bp;
355 u32 val = 0;
356
357 if ((1 < strict_cos) && (NULL == params))
358 return -EINVAL;
359
360 DP(NETIF_MSG_LINK, "ETS enabled strict configuration\n");
361 /**
362 * Bitmap of 5bits length. Each bit specifies whether the entry behaves
363 * as strict. Bits 0,1,2 - debug and management entries,
364 * 3 - COS0 entry, 4 - COS1 entry.
365 * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
366 * bit4 bit3 bit2 bit1 bit0
367 * MCP and debug are strict
368 */
369 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1F);
370 /**
371 * For strict priority entries defines the number of consecutive slots
372 * for the highest priority.
373 */
374 REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
375 /* ETS mode disable */
376 REG_WR(bp, PBF_REG_ETS_ENABLED, 0);
377 /* Defines the number of consecutive slots for the strict priority */
378 REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0x100);
379
380 /* Defines the number of consecutive slots for the strict priority */
381 REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, strict_cos);
382
383 /**
384 * mapping between entry priority to client number (0,1,2 -debug and
385 * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
386 * 3bits client num.
387 * PRI4 | PRI3 | PRI2 | PRI1 | PRI0
388 * dbg0-010 dbg1-001 cos1-100 cos0-011 MCP-000
389 * dbg0-010 dbg1-001 cos0-011 cos1-100 MCP-000
390 */
391 val = (0 == strict_cos) ? 0x2318 : 0x22E0;
392 REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, val);
393
394 return 0;
395}
396/******************************************************************/
397/* ETS section */
398/******************************************************************/
399
400static void bnx2x_bmac2_get_pfc_stat(struct link_params *params,
401 u32 pfc_frames_sent[2],
402 u32 pfc_frames_received[2])
403{
404 /* Read pfc statistic */
405 struct bnx2x *bp = params->bp;
406 u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
407 NIG_REG_INGRESS_BMAC0_MEM;
408
409 DP(NETIF_MSG_LINK, "pfc statistic read from BMAC\n");
410
411 REG_RD_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_STAT_GTPP,
412 pfc_frames_sent, 2);
413
414 REG_RD_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_STAT_GRPP,
415 pfc_frames_received, 2);
416
417}
418static void bnx2x_emac_get_pfc_stat(struct link_params *params,
419 u32 pfc_frames_sent[2],
420 u32 pfc_frames_received[2])
421{
422 /* Read pfc statistic */
423 struct bnx2x *bp = params->bp;
424 u32 emac_base = params->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
425 u32 val_xon = 0;
426 u32 val_xoff = 0;
427
428 DP(NETIF_MSG_LINK, "pfc statistic read from EMAC\n");
429
430 /* PFC received frames */
431 val_xoff = REG_RD(bp, emac_base +
432 EMAC_REG_RX_PFC_STATS_XOFF_RCVD);
433 val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_RCVD_COUNT;
434 val_xon = REG_RD(bp, emac_base + EMAC_REG_RX_PFC_STATS_XON_RCVD);
435 val_xon &= EMAC_REG_RX_PFC_STATS_XON_RCVD_COUNT;
436
437 pfc_frames_received[0] = val_xon + val_xoff;
438
439 /* PFC received sent */
440 val_xoff = REG_RD(bp, emac_base +
441 EMAC_REG_RX_PFC_STATS_XOFF_SENT);
442 val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_SENT_COUNT;
443 val_xon = REG_RD(bp, emac_base + EMAC_REG_RX_PFC_STATS_XON_SENT);
444 val_xon &= EMAC_REG_RX_PFC_STATS_XON_SENT_COUNT;
445
446 pfc_frames_sent[0] = val_xon + val_xoff;
447}
448
449void bnx2x_pfc_statistic(struct link_params *params, struct link_vars *vars,
450 u32 pfc_frames_sent[2],
451 u32 pfc_frames_received[2])
452{
453 /* Read pfc statistic */
454 struct bnx2x *bp = params->bp;
455 u32 val = 0;
456 DP(NETIF_MSG_LINK, "pfc statistic\n");
457
458 if (!vars->link_up)
459 return;
460
461 val = REG_RD(bp, MISC_REG_RESET_REG_2);
462 if ((val & (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))
463 == 0) {
464 DP(NETIF_MSG_LINK, "About to read stats from EMAC\n");
465 bnx2x_emac_get_pfc_stat(params, pfc_frames_sent,
466 pfc_frames_received);
467 } else {
468 DP(NETIF_MSG_LINK, "About to read stats from BMAC\n");
469 bnx2x_bmac2_get_pfc_stat(params, pfc_frames_sent,
470 pfc_frames_received);
471 }
472}
473/******************************************************************/
474/* MAC/PBF section */
475/******************************************************************/
208static void bnx2x_emac_init(struct link_params *params, 476static void bnx2x_emac_init(struct link_params *params,
209 struct link_vars *vars) 477 struct link_vars *vars)
210{ 478{
@@ -315,24 +583,55 @@ static u8 bnx2x_emac_enable(struct link_params *params,
315 /* pause enable/disable */ 583 /* pause enable/disable */
316 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE, 584 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
317 EMAC_RX_MODE_FLOW_EN); 585 EMAC_RX_MODE_FLOW_EN);
318 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
319 bnx2x_bits_en(bp, emac_base +
320 EMAC_REG_EMAC_RX_MODE,
321 EMAC_RX_MODE_FLOW_EN);
322 586
323 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_TX_MODE, 587 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
324 (EMAC_TX_MODE_EXT_PAUSE_EN | 588 (EMAC_TX_MODE_EXT_PAUSE_EN |
325 EMAC_TX_MODE_FLOW_EN)); 589 EMAC_TX_MODE_FLOW_EN));
326 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) 590 if (!(params->feature_config_flags &
327 bnx2x_bits_en(bp, emac_base + 591 FEATURE_CONFIG_PFC_ENABLED)) {
328 EMAC_REG_EMAC_TX_MODE, 592 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
329 (EMAC_TX_MODE_EXT_PAUSE_EN | 593 bnx2x_bits_en(bp, emac_base +
330 EMAC_TX_MODE_FLOW_EN)); 594 EMAC_REG_EMAC_RX_MODE,
595 EMAC_RX_MODE_FLOW_EN);
596
597 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
598 bnx2x_bits_en(bp, emac_base +
599 EMAC_REG_EMAC_TX_MODE,
600 (EMAC_TX_MODE_EXT_PAUSE_EN |
601 EMAC_TX_MODE_FLOW_EN));
602 } else
603 bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
604 EMAC_TX_MODE_FLOW_EN);
331 } 605 }
332 606
333 /* KEEP_VLAN_TAG, promiscuous */ 607 /* KEEP_VLAN_TAG, promiscuous */
334 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE); 608 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
335 val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS; 609 val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
610
611 /**
612 * Setting this bit causes MAC control frames (except for pause
613 * frames) to be passed on for processing. This setting has no
614 * affect on the operation of the pause frames. This bit effects
615 * all packets regardless of RX Parser packet sorting logic.
616 * Turn the PFC off to make sure we are in Xon state before
617 * enabling it.
618 */
619 EMAC_WR(bp, EMAC_REG_RX_PFC_MODE, 0);
620 if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) {
621 DP(NETIF_MSG_LINK, "PFC is enabled\n");
622 /* Enable PFC again */
623 EMAC_WR(bp, EMAC_REG_RX_PFC_MODE,
624 EMAC_REG_RX_PFC_MODE_RX_EN |
625 EMAC_REG_RX_PFC_MODE_TX_EN |
626 EMAC_REG_RX_PFC_MODE_PRIORITIES);
627
628 EMAC_WR(bp, EMAC_REG_RX_PFC_PARAM,
629 ((0x0101 <<
630 EMAC_REG_RX_PFC_PARAM_OPCODE_BITSHIFT) |
631 (0x00ff <<
632 EMAC_REG_RX_PFC_PARAM_PRIORITY_EN_BITSHIFT)));
633 val |= EMAC_RX_MODE_KEEP_MAC_CONTROL;
634 }
336 EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val); 635 EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
337 636
338 /* Set Loopback */ 637 /* Set Loopback */
@@ -362,7 +661,9 @@ static u8 bnx2x_emac_enable(struct link_params *params,
362 /* enable the NIG in/out to the emac */ 661 /* enable the NIG in/out to the emac */
363 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1); 662 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
364 val = 0; 663 val = 0;
365 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) 664 if ((params->feature_config_flags &
665 FEATURE_CONFIG_PFC_ENABLED) ||
666 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
366 val = 1; 667 val = 1;
367 668
368 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val); 669 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
@@ -383,9 +684,38 @@ static u8 bnx2x_emac_enable(struct link_params *params,
383 return 0; 684 return 0;
384} 685}
385 686
386static void bnx2x_update_bmac2(struct link_params *params, 687static void bnx2x_update_pfc_bmac1(struct link_params *params,
387 struct link_vars *vars, 688 struct link_vars *vars)
388 u8 is_lb) 689{
690 u32 wb_data[2];
691 struct bnx2x *bp = params->bp;
692 u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
693 NIG_REG_INGRESS_BMAC0_MEM;
694
695 u32 val = 0x14;
696 if ((!(params->feature_config_flags &
697 FEATURE_CONFIG_PFC_ENABLED)) &&
698 (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
699 /* Enable BigMAC to react on received Pause packets */
700 val |= (1<<5);
701 wb_data[0] = val;
702 wb_data[1] = 0;
703 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL, wb_data, 2);
704
705 /* tx control */
706 val = 0xc0;
707 if (!(params->feature_config_flags &
708 FEATURE_CONFIG_PFC_ENABLED) &&
709 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
710 val |= 0x800000;
711 wb_data[0] = val;
712 wb_data[1] = 0;
713 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL, wb_data, 2);
714}
715
716static void bnx2x_update_pfc_bmac2(struct link_params *params,
717 struct link_vars *vars,
718 u8 is_lb)
389{ 719{
390 /* 720 /*
391 * Set rx control: Strip CRC and enable BigMAC to relay 721 * Set rx control: Strip CRC and enable BigMAC to relay
@@ -397,7 +727,9 @@ static void bnx2x_update_bmac2(struct link_params *params,
397 NIG_REG_INGRESS_BMAC0_MEM; 727 NIG_REG_INGRESS_BMAC0_MEM;
398 u32 val = 0x14; 728 u32 val = 0x14;
399 729
400 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX) 730 if ((!(params->feature_config_flags &
731 FEATURE_CONFIG_PFC_ENABLED)) &&
732 (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
401 /* Enable BigMAC to react on received Pause packets */ 733 /* Enable BigMAC to react on received Pause packets */
402 val |= (1<<5); 734 val |= (1<<5);
403 wb_data[0] = val; 735 wb_data[0] = val;
@@ -408,14 +740,47 @@ static void bnx2x_update_bmac2(struct link_params *params,
408 740
409 /* Tx control */ 741 /* Tx control */
410 val = 0xc0; 742 val = 0xc0;
411 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) 743 if (!(params->feature_config_flags &
744 FEATURE_CONFIG_PFC_ENABLED) &&
745 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
412 val |= 0x800000; 746 val |= 0x800000;
413 wb_data[0] = val; 747 wb_data[0] = val;
414 wb_data[1] = 0; 748 wb_data[1] = 0;
415 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL, 749 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL, wb_data, 2);
416 wb_data, 2); 750
751 if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) {
752 DP(NETIF_MSG_LINK, "PFC is enabled\n");
753 /* Enable PFC RX & TX & STATS and set 8 COS */
754 wb_data[0] = 0x0;
755 wb_data[0] |= (1<<0); /* RX */
756 wb_data[0] |= (1<<1); /* TX */
757 wb_data[0] |= (1<<2); /* Force initial Xon */
758 wb_data[0] |= (1<<3); /* 8 cos */
759 wb_data[0] |= (1<<5); /* STATS */
760 wb_data[1] = 0;
761 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL,
762 wb_data, 2);
763 /* Clear the force Xon */
764 wb_data[0] &= ~(1<<2);
765 } else {
766 DP(NETIF_MSG_LINK, "PFC is disabled\n");
767 /* disable PFC RX & TX & STATS and set 8 COS */
768 wb_data[0] = 0x8;
769 wb_data[1] = 0;
770 }
771
772 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL, wb_data, 2);
417 773
774 /**
775 * Set Time (based unit is 512 bit time) between automatic
776 * re-sending of PP packets amd enable automatic re-send of
777 * Per-Priroity Packet as long as pp_gen is asserted and
778 * pp_disable is low.
779 */
418 val = 0x8000; 780 val = 0x8000;
781 if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
782 val |= (1<<16); /* enable automatic re-send */
783
419 wb_data[0] = val; 784 wb_data[0] = val;
420 wb_data[1] = 0; 785 wb_data[1] = 0;
421 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL, 786 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL,
@@ -427,6 +792,9 @@ static void bnx2x_update_bmac2(struct link_params *params,
427 val |= 0x4; /* Local loopback */ 792 val |= 0x4; /* Local loopback */
428 DP(NETIF_MSG_LINK, "enable bmac loopback\n"); 793 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
429 } 794 }
795 /* When PFC enabled, Pass pause frames towards the NIG. */
796 if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
797 val |= ((1<<6)|(1<<5));
430 798
431 wb_data[0] = val; 799 wb_data[0] = val;
432 wb_data[1] = 0; 800 wb_data[1] = 0;
@@ -434,6 +802,239 @@ static void bnx2x_update_bmac2(struct link_params *params,
434 wb_data, 2); 802 wb_data, 2);
435} 803}
436 804
805static void bnx2x_update_pfc_brb(struct link_params *params,
806 struct link_vars *vars,
807 struct bnx2x_nig_brb_pfc_port_params *pfc_params)
808{
809 struct bnx2x *bp = params->bp;
810 int set_pfc = params->feature_config_flags &
811 FEATURE_CONFIG_PFC_ENABLED;
812
813 /* default - pause configuration */
814 u32 pause_xoff_th = PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_PAUSEABLE;
815 u32 pause_xon_th = PFC_BRB_MAC_PAUSE_XON_THRESHOLD_PAUSEABLE;
816 u32 full_xoff_th = PFC_BRB_MAC_FULL_XOFF_THRESHOLD_PAUSEABLE;
817 u32 full_xon_th = PFC_BRB_MAC_FULL_XON_THRESHOLD_PAUSEABLE;
818
819 if (set_pfc && pfc_params)
820 /* First COS */
821 if (!pfc_params->cos0_pauseable) {
822 pause_xoff_th =
823 PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_NON_PAUSEABLE;
824 pause_xon_th =
825 PFC_BRB_MAC_PAUSE_XON_THRESHOLD_NON_PAUSEABLE;
826 full_xoff_th =
827 PFC_BRB_MAC_FULL_XOFF_THRESHOLD_NON_PAUSEABLE;
828 full_xon_th =
829 PFC_BRB_MAC_FULL_XON_THRESHOLD_NON_PAUSEABLE;
830 }
831 /* The number of free blocks below which the pause signal to class 0
832 of MAC #n is asserted. n=0,1 */
833 REG_WR(bp, BRB1_REG_PAUSE_0_XOFF_THRESHOLD_0 , pause_xoff_th);
834 /* The number of free blocks above which the pause signal to class 0
835 of MAC #n is de-asserted. n=0,1 */
836 REG_WR(bp, BRB1_REG_PAUSE_0_XON_THRESHOLD_0 , pause_xon_th);
837 /* The number of free blocks below which the full signal to class 0
838 of MAC #n is asserted. n=0,1 */
839 REG_WR(bp, BRB1_REG_FULL_0_XOFF_THRESHOLD_0 , full_xoff_th);
840 /* The number of free blocks above which the full signal to class 0
841 of MAC #n is de-asserted. n=0,1 */
842 REG_WR(bp, BRB1_REG_FULL_0_XON_THRESHOLD_0 , full_xon_th);
843
844 if (set_pfc && pfc_params) {
845 /* Second COS */
846 if (pfc_params->cos1_pauseable) {
847 pause_xoff_th =
848 PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_PAUSEABLE;
849 pause_xon_th =
850 PFC_BRB_MAC_PAUSE_XON_THRESHOLD_PAUSEABLE;
851 full_xoff_th =
852 PFC_BRB_MAC_FULL_XOFF_THRESHOLD_PAUSEABLE;
853 full_xon_th =
854 PFC_BRB_MAC_FULL_XON_THRESHOLD_PAUSEABLE;
855 } else {
856 pause_xoff_th =
857 PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_NON_PAUSEABLE;
858 pause_xon_th =
859 PFC_BRB_MAC_PAUSE_XON_THRESHOLD_NON_PAUSEABLE;
860 full_xoff_th =
861 PFC_BRB_MAC_FULL_XOFF_THRESHOLD_NON_PAUSEABLE;
862 full_xon_th =
863 PFC_BRB_MAC_FULL_XON_THRESHOLD_NON_PAUSEABLE;
864 }
865 /**
866 * The number of free blocks below which the pause signal to
867 * class 1 of MAC #n is asserted. n=0,1
868 **/
869 REG_WR(bp, BRB1_REG_PAUSE_1_XOFF_THRESHOLD_0, pause_xoff_th);
870 /**
871 * The number of free blocks above which the pause signal to
872 * class 1 of MAC #n is de-asserted. n=0,1
873 **/
874 REG_WR(bp, BRB1_REG_PAUSE_1_XON_THRESHOLD_0, pause_xon_th);
875 /**
876 * The number of free blocks below which the full signal to
877 * class 1 of MAC #n is asserted. n=0,1
878 **/
879 REG_WR(bp, BRB1_REG_FULL_1_XOFF_THRESHOLD_0, full_xoff_th);
880 /**
881 * The number of free blocks above which the full signal to
882 * class 1 of MAC #n is de-asserted. n=0,1
883 **/
884 REG_WR(bp, BRB1_REG_FULL_1_XON_THRESHOLD_0, full_xon_th);
885 }
886}
887
888static void bnx2x_update_pfc_nig(struct link_params *params,
889 struct link_vars *vars,
890 struct bnx2x_nig_brb_pfc_port_params *nig_params)
891{
892 u32 xcm_mask = 0, ppp_enable = 0, pause_enable = 0, llfc_out_en = 0;
893 u32 llfc_enable = 0, xcm0_out_en = 0, p0_hwpfc_enable = 0;
894 u32 pkt_priority_to_cos = 0;
895 u32 val;
896 struct bnx2x *bp = params->bp;
897 int port = params->port;
898 int set_pfc = params->feature_config_flags &
899 FEATURE_CONFIG_PFC_ENABLED;
900 DP(NETIF_MSG_LINK, "updating pfc nig parameters\n");
901
902 /**
903 * When NIG_LLH0_XCM_MASK_REG_LLHX_XCM_MASK_BCN bit is set
904 * MAC control frames (that are not pause packets)
905 * will be forwarded to the XCM.
906 */
907 xcm_mask = REG_RD(bp,
908 port ? NIG_REG_LLH1_XCM_MASK :
909 NIG_REG_LLH0_XCM_MASK);
910 /**
911 * nig params will override non PFC params, since it's possible to
912 * do transition from PFC to SAFC
913 */
914 if (set_pfc) {
915 pause_enable = 0;
916 llfc_out_en = 0;
917 llfc_enable = 0;
918 ppp_enable = 1;
919 xcm_mask &= ~(port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
920 NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
921 xcm0_out_en = 0;
922 p0_hwpfc_enable = 1;
923 } else {
924 if (nig_params) {
925 llfc_out_en = nig_params->llfc_out_en;
926 llfc_enable = nig_params->llfc_enable;
927 pause_enable = nig_params->pause_enable;
928 } else /*defaul non PFC mode - PAUSE */
929 pause_enable = 1;
930
931 xcm_mask |= (port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
932 NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
933 xcm0_out_en = 1;
934 }
935
936 REG_WR(bp, port ? NIG_REG_LLFC_OUT_EN_1 :
937 NIG_REG_LLFC_OUT_EN_0, llfc_out_en);
938 REG_WR(bp, port ? NIG_REG_LLFC_ENABLE_1 :
939 NIG_REG_LLFC_ENABLE_0, llfc_enable);
940 REG_WR(bp, port ? NIG_REG_PAUSE_ENABLE_1 :
941 NIG_REG_PAUSE_ENABLE_0, pause_enable);
942
943 REG_WR(bp, port ? NIG_REG_PPP_ENABLE_1 :
944 NIG_REG_PPP_ENABLE_0, ppp_enable);
945
946 REG_WR(bp, port ? NIG_REG_LLH1_XCM_MASK :
947 NIG_REG_LLH0_XCM_MASK, xcm_mask);
948
949 REG_WR(bp, NIG_REG_LLFC_EGRESS_SRC_ENABLE_0, 0x7);
950
951 /* output enable for RX_XCM # IF */
952 REG_WR(bp, NIG_REG_XCM0_OUT_EN, xcm0_out_en);
953
954 /* HW PFC TX enable */
955 REG_WR(bp, NIG_REG_P0_HWPFC_ENABLE, p0_hwpfc_enable);
956
957 /* 0x2 = BMAC, 0x1= EMAC */
958 switch (vars->mac_type) {
959 case MAC_TYPE_EMAC:
960 val = 1;
961 break;
962 case MAC_TYPE_BMAC:
963 val = 0;
964 break;
965 default:
966 val = 0;
967 break;
968 }
969 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT, val);
970
971 if (nig_params) {
972 pkt_priority_to_cos = nig_params->pkt_priority_to_cos;
973
974 REG_WR(bp, port ? NIG_REG_P1_RX_COS0_PRIORITY_MASK :
975 NIG_REG_P0_RX_COS0_PRIORITY_MASK,
976 nig_params->rx_cos0_priority_mask);
977
978 REG_WR(bp, port ? NIG_REG_P1_RX_COS1_PRIORITY_MASK :
979 NIG_REG_P0_RX_COS1_PRIORITY_MASK,
980 nig_params->rx_cos1_priority_mask);
981
982 REG_WR(bp, port ? NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_1 :
983 NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0,
984 nig_params->llfc_high_priority_classes);
985
986 REG_WR(bp, port ? NIG_REG_LLFC_LOW_PRIORITY_CLASSES_1 :
987 NIG_REG_LLFC_LOW_PRIORITY_CLASSES_0,
988 nig_params->llfc_low_priority_classes);
989 }
990 REG_WR(bp, port ? NIG_REG_P1_PKT_PRIORITY_TO_COS :
991 NIG_REG_P0_PKT_PRIORITY_TO_COS,
992 pkt_priority_to_cos);
993}
994
995
996void bnx2x_update_pfc(struct link_params *params,
997 struct link_vars *vars,
998 struct bnx2x_nig_brb_pfc_port_params *pfc_params)
999{
1000 /**
1001 * The PFC and pause are orthogonal to one another, meaning when
1002 * PFC is enabled, the pause are disabled, and when PFC is
1003 * disabled, pause are set according to the pause result.
1004 */
1005 u32 val;
1006 struct bnx2x *bp = params->bp;
1007
1008 /* update NIG params */
1009 bnx2x_update_pfc_nig(params, vars, pfc_params);
1010
1011 /* update BRB params */
1012 bnx2x_update_pfc_brb(params, vars, pfc_params);
1013
1014 if (!vars->link_up)
1015 return;
1016
1017 val = REG_RD(bp, MISC_REG_RESET_REG_2);
1018 if ((val & (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))
1019 == 0) {
1020 DP(NETIF_MSG_LINK, "About to update PFC in EMAC\n");
1021 bnx2x_emac_enable(params, vars, 0);
1022 return;
1023 }
1024
1025 DP(NETIF_MSG_LINK, "About to update PFC in BMAC\n");
1026 if (CHIP_IS_E2(bp))
1027 bnx2x_update_pfc_bmac2(params, vars, 0);
1028 else
1029 bnx2x_update_pfc_bmac1(params, vars);
1030
1031 val = 0;
1032 if ((params->feature_config_flags &
1033 FEATURE_CONFIG_PFC_ENABLED) ||
1034 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1035 val = 1;
1036 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + params->port*4, val);
1037}
437 1038
438static u8 bnx2x_bmac1_enable(struct link_params *params, 1039static u8 bnx2x_bmac1_enable(struct link_params *params,
439 struct link_vars *vars, 1040 struct link_vars *vars,
@@ -465,15 +1066,6 @@ static u8 bnx2x_bmac1_enable(struct link_params *params,
465 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR, 1066 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR,
466 wb_data, 2); 1067 wb_data, 2);
467 1068
468 /* tx control */
469 val = 0xc0;
470 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
471 val |= 0x800000;
472 wb_data[0] = val;
473 wb_data[1] = 0;
474 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL,
475 wb_data, 2);
476
477 /* mac control */ 1069 /* mac control */
478 val = 0x3; 1070 val = 0x3;
479 if (is_lb) { 1071 if (is_lb) {
@@ -491,14 +1083,7 @@ static u8 bnx2x_bmac1_enable(struct link_params *params,
491 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE, 1083 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE,
492 wb_data, 2); 1084 wb_data, 2);
493 1085
494 /* rx control set to don't strip crc */ 1086 bnx2x_update_pfc_bmac1(params, vars);
495 val = 0x14;
496 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
497 val |= 0x20;
498 wb_data[0] = val;
499 wb_data[1] = 0;
500 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL,
501 wb_data, 2);
502 1087
503 /* set tx mtu */ 1088 /* set tx mtu */
504 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD; 1089 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
@@ -595,7 +1180,7 @@ static u8 bnx2x_bmac2_enable(struct link_params *params,
595 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE, 1180 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE,
596 wb_data, 2); 1181 wb_data, 2);
597 udelay(30); 1182 udelay(30);
598 bnx2x_update_bmac2(params, vars, is_lb); 1183 bnx2x_update_pfc_bmac2(params, vars, is_lb);
599 1184
600 return 0; 1185 return 0;
601} 1186}
@@ -627,7 +1212,9 @@ static u8 bnx2x_bmac_enable(struct link_params *params,
627 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0); 1212 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
628 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0); 1213 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
629 val = 0; 1214 val = 0;
630 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) 1215 if ((params->feature_config_flags &
1216 FEATURE_CONFIG_PFC_ENABLED) ||
1217 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
631 val = 1; 1218 val = 1;
632 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val); 1219 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
633 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0); 1220 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);