diff options
author | Vladislav Zolotarov <vladz@broadcom.com> | 2010-12-13 00:44:25 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-12-16 16:15:55 -0500 |
commit | bcab15c5d780bafb38311f00fcb263d03d2b00f1 (patch) | |
tree | c50e4971d9c0d071b65dc4c849828d46140fb3a9 /drivers/net/bnx2x | |
parent | e4901dde12d92b70dd13fa8b3bbc9df7a6129aab (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')
-rw-r--r-- | drivers/net/bnx2x/bnx2x_link.c | 665 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_link.h | 16 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_reg.h | 47 |
3 files changed, 689 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 | /******************************************************************/ | ||
212 | void 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 | |||
271 | void 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 | |||
318 | void 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 | |||
351 | u8 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 | |||
400 | static 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 | } | ||
418 | static 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 | |||
449 | void 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 | /******************************************************************/ | ||
208 | static void bnx2x_emac_init(struct link_params *params, | 476 | static 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 | ||
386 | static void bnx2x_update_bmac2(struct link_params *params, | 687 | static 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 | |||
716 | static 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 | ||
805 | static 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 | |||
888 | static 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 | |||
996 | void 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 | ||
438 | static u8 bnx2x_bmac1_enable(struct link_params *params, | 1039 | static 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); |
diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h index 149f84258d8b..bedab1a942c4 100644 --- a/drivers/net/bnx2x/bnx2x_link.h +++ b/drivers/net/bnx2x/bnx2x_link.h | |||
@@ -65,6 +65,22 @@ | |||
65 | #define FW_PARAM_MDIO_CTRL_OFFSET 16 | 65 | #define FW_PARAM_MDIO_CTRL_OFFSET 16 |
66 | #define FW_PARAM_SET(phy_addr, phy_type, mdio_access) \ | 66 | #define FW_PARAM_SET(phy_addr, phy_type, mdio_access) \ |
67 | (phy_addr | phy_type | mdio_access << FW_PARAM_MDIO_CTRL_OFFSET) | 67 | (phy_addr | phy_type | mdio_access << FW_PARAM_MDIO_CTRL_OFFSET) |
68 | |||
69 | #define PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_PAUSEABLE 170 | ||
70 | #define PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_NON_PAUSEABLE 0 | ||
71 | |||
72 | #define PFC_BRB_MAC_PAUSE_XON_THRESHOLD_PAUSEABLE 250 | ||
73 | #define PFC_BRB_MAC_PAUSE_XON_THRESHOLD_NON_PAUSEABLE 0 | ||
74 | |||
75 | #define PFC_BRB_MAC_FULL_XOFF_THRESHOLD_PAUSEABLE 10 | ||
76 | #define PFC_BRB_MAC_FULL_XOFF_THRESHOLD_NON_PAUSEABLE 90 | ||
77 | |||
78 | #define PFC_BRB_MAC_FULL_XON_THRESHOLD_PAUSEABLE 50 | ||
79 | #define PFC_BRB_MAC_FULL_XON_THRESHOLD_NON_PAUSEABLE 250 | ||
80 | |||
81 | #define PFC_BRB_FULL_LB_XOFF_THRESHOLD 170 | ||
82 | #define PFC_BRB_FULL_LB_XON_THRESHOLD 250 | ||
83 | |||
68 | /***********************************************************/ | 84 | /***********************************************************/ |
69 | /* Structs */ | 85 | /* Structs */ |
70 | /***********************************************************/ | 86 | /***********************************************************/ |
diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 64bdda189e5a..bfd875b72906 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h | |||
@@ -1615,6 +1615,8 @@ | |||
1615 | #define NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_NO_VLAN (0x1<<4) | 1615 | #define NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_NO_VLAN (0x1<<4) |
1616 | #define NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_UNCST (0x1<<2) | 1616 | #define NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_UNCST (0x1<<2) |
1617 | #define NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_VLAN (0x1<<3) | 1617 | #define NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_VLAN (0x1<<3) |
1618 | #define NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN (0x1<<0) | ||
1619 | #define NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN (0x1<<0) | ||
1618 | #define NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT (0x1<<0) | 1620 | #define NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT (0x1<<0) |
1619 | #define NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS (0x1<<9) | 1621 | #define NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS (0x1<<9) |
1620 | #define NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G (0x1<<15) | 1622 | #define NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G (0x1<<15) |
@@ -1744,12 +1746,16 @@ | |||
1744 | ~ppp_enable.ppp_enable = 0 and pause_enable.pause_enable =0 for the same | 1746 | ~ppp_enable.ppp_enable = 0 and pause_enable.pause_enable =0 for the same |
1745 | port */ | 1747 | port */ |
1746 | #define NIG_REG_LLFC_ENABLE_0 0x16208 | 1748 | #define NIG_REG_LLFC_ENABLE_0 0x16208 |
1749 | #define NIG_REG_LLFC_ENABLE_1 0x1620c | ||
1747 | /* [RW 16] classes are high-priority for port0 */ | 1750 | /* [RW 16] classes are high-priority for port0 */ |
1748 | #define NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0 0x16058 | 1751 | #define NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0 0x16058 |
1752 | #define NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_1 0x1605c | ||
1749 | /* [RW 16] classes are low-priority for port0 */ | 1753 | /* [RW 16] classes are low-priority for port0 */ |
1750 | #define NIG_REG_LLFC_LOW_PRIORITY_CLASSES_0 0x16060 | 1754 | #define NIG_REG_LLFC_LOW_PRIORITY_CLASSES_0 0x16060 |
1755 | #define NIG_REG_LLFC_LOW_PRIORITY_CLASSES_1 0x16064 | ||
1751 | /* [RW 1] Output enable of message to LLFC BMAC IF for port0 */ | 1756 | /* [RW 1] Output enable of message to LLFC BMAC IF for port0 */ |
1752 | #define NIG_REG_LLFC_OUT_EN_0 0x160c8 | 1757 | #define NIG_REG_LLFC_OUT_EN_0 0x160c8 |
1758 | #define NIG_REG_LLFC_OUT_EN_1 0x160cc | ||
1753 | #define NIG_REG_LLH0_ACPI_PAT_0_CRC 0x1015c | 1759 | #define NIG_REG_LLH0_ACPI_PAT_0_CRC 0x1015c |
1754 | #define NIG_REG_LLH0_ACPI_PAT_6_LEN 0x10154 | 1760 | #define NIG_REG_LLH0_ACPI_PAT_6_LEN 0x10154 |
1755 | #define NIG_REG_LLH0_BRB1_DRV_MASK 0x10244 | 1761 | #define NIG_REG_LLH0_BRB1_DRV_MASK 0x10244 |
@@ -1912,11 +1918,17 @@ | |||
1912 | ~safc_enable.safc_enable = 0 and ppp_enable.ppp_enable =0 for the same | 1918 | ~safc_enable.safc_enable = 0 and ppp_enable.ppp_enable =0 for the same |
1913 | port */ | 1919 | port */ |
1914 | #define NIG_REG_PAUSE_ENABLE_0 0x160c0 | 1920 | #define NIG_REG_PAUSE_ENABLE_0 0x160c0 |
1921 | #define NIG_REG_PAUSE_ENABLE_1 0x160c4 | ||
1915 | /* [RW 1] Input enable for RX PBF LP IF */ | 1922 | /* [RW 1] Input enable for RX PBF LP IF */ |
1916 | #define NIG_REG_PBF_LB_IN_EN 0x100b4 | 1923 | #define NIG_REG_PBF_LB_IN_EN 0x100b4 |
1917 | /* [RW 1] Value of this register will be transmitted to port swap when | 1924 | /* [RW 1] Value of this register will be transmitted to port swap when |
1918 | ~nig_registers_strap_override.strap_override =1 */ | 1925 | ~nig_registers_strap_override.strap_override =1 */ |
1919 | #define NIG_REG_PORT_SWAP 0x10394 | 1926 | #define NIG_REG_PORT_SWAP 0x10394 |
1927 | /* [RW 1] PPP enable for port0. This register may get 1 only when | ||
1928 | * ~safc_enable.safc_enable = 0 and pause_enable.pause_enable =0 for the | ||
1929 | * same port */ | ||
1930 | #define NIG_REG_PPP_ENABLE_0 0x160b0 | ||
1931 | #define NIG_REG_PPP_ENABLE_1 0x160b4 | ||
1920 | /* [RW 1] output enable for RX parser descriptor IF */ | 1932 | /* [RW 1] output enable for RX parser descriptor IF */ |
1921 | #define NIG_REG_PRS_EOP_OUT_EN 0x10104 | 1933 | #define NIG_REG_PRS_EOP_OUT_EN 0x10104 |
1922 | /* [RW 1] Input enable for RX parser request IF */ | 1934 | /* [RW 1] Input enable for RX parser request IF */ |
@@ -1983,6 +1995,14 @@ | |||
1983 | #define NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G (0x1<<15) | 1995 | #define NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G (0x1<<15) |
1984 | #define NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS (0xf<<18) | 1996 | #define NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS (0xf<<18) |
1985 | #define NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE 18 | 1997 | #define NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE 18 |
1998 | /* [RW 31] The upper bound of the weight of COS0 in the ETS command arbiter. */ | ||
1999 | #define PBF_REG_COS0_UPPER_BOUND 0x15c05c | ||
2000 | /* [RW 31] The weight of COS0 in the ETS command arbiter. */ | ||
2001 | #define PBF_REG_COS0_WEIGHT 0x15c054 | ||
2002 | /* [RW 31] The upper bound of the weight of COS1 in the ETS command arbiter. */ | ||
2003 | #define PBF_REG_COS1_UPPER_BOUND 0x15c060 | ||
2004 | /* [RW 31] The weight of COS1 in the ETS command arbiter. */ | ||
2005 | #define PBF_REG_COS1_WEIGHT 0x15c058 | ||
1986 | /* [RW 1] Disable processing further tasks from port 0 (after ending the | 2006 | /* [RW 1] Disable processing further tasks from port 0 (after ending the |
1987 | current task in process). */ | 2007 | current task in process). */ |
1988 | #define PBF_REG_DISABLE_NEW_TASK_PROC_P0 0x14005c | 2008 | #define PBF_REG_DISABLE_NEW_TASK_PROC_P0 0x14005c |
@@ -1993,9 +2013,16 @@ | |||
1993 | current task in process). */ | 2013 | current task in process). */ |
1994 | #define PBF_REG_DISABLE_NEW_TASK_PROC_P4 0x14006c | 2014 | #define PBF_REG_DISABLE_NEW_TASK_PROC_P4 0x14006c |
1995 | #define PBF_REG_DISABLE_PF 0x1402e8 | 2015 | #define PBF_REG_DISABLE_PF 0x1402e8 |
2016 | /* [RW 1] Indicates that ETS is performed between the COSes in the command | ||
2017 | * arbiter. If reset strict priority w/ anti-starvation will be performed | ||
2018 | * w/o WFQ. */ | ||
2019 | #define PBF_REG_ETS_ENABLED 0x15c050 | ||
1996 | /* [RW 6] Bit-map indicating which L2 hdrs may appear after the basic | 2020 | /* [RW 6] Bit-map indicating which L2 hdrs may appear after the basic |
1997 | * Ethernet header. */ | 2021 | * Ethernet header. */ |
1998 | #define PBF_REG_HDRS_AFTER_BASIC 0x15c0a8 | 2022 | #define PBF_REG_HDRS_AFTER_BASIC 0x15c0a8 |
2023 | /* [RW 1] Indicates which COS is conncted to the highest priority in the | ||
2024 | * command arbiter. */ | ||
2025 | #define PBF_REG_HIGH_PRIORITY_COS_NUM 0x15c04c | ||
1999 | #define PBF_REG_IF_ENABLE_REG 0x140044 | 2026 | #define PBF_REG_IF_ENABLE_REG 0x140044 |
2000 | /* [RW 1] Init bit. When set the initial credits are copied to the credit | 2027 | /* [RW 1] Init bit. When set the initial credits are copied to the credit |
2001 | registers (except the port credits). Should be set and then reset after | 2028 | registers (except the port credits). Should be set and then reset after |
@@ -2021,6 +2048,10 @@ | |||
2021 | #define PBF_REG_MAC_LB_ENABLE 0x140040 | 2048 | #define PBF_REG_MAC_LB_ENABLE 0x140040 |
2022 | /* [RW 6] Bit-map indicating which headers must appear in the packet */ | 2049 | /* [RW 6] Bit-map indicating which headers must appear in the packet */ |
2023 | #define PBF_REG_MUST_HAVE_HDRS 0x15c0c4 | 2050 | #define PBF_REG_MUST_HAVE_HDRS 0x15c0c4 |
2051 | /* [RW 16] The number of strict priority arbitration slots between 2 RR | ||
2052 | * arbitration slots. A value of 0 means no strict priority cycles; i.e. the | ||
2053 | * strict-priority w/ anti-starvation arbiter is a RR arbiter. */ | ||
2054 | #define PBF_REG_NUM_STRICT_ARB_SLOTS 0x15c064 | ||
2024 | /* [RW 10] Port 0 threshold used by arbiter in 16 byte lines used when pause | 2055 | /* [RW 10] Port 0 threshold used by arbiter in 16 byte lines used when pause |
2025 | not suppoterd. */ | 2056 | not suppoterd. */ |
2026 | #define PBF_REG_P0_ARB_THRSH 0x1400e4 | 2057 | #define PBF_REG_P0_ARB_THRSH 0x1400e4 |
@@ -4975,7 +5006,23 @@ | |||
4975 | #define EMAC_REG_EMAC_TX_MODE 0xbc | 5006 | #define EMAC_REG_EMAC_TX_MODE 0xbc |
4976 | #define EMAC_REG_EMAC_TX_STAT_AC 0x280 | 5007 | #define EMAC_REG_EMAC_TX_STAT_AC 0x280 |
4977 | #define EMAC_REG_EMAC_TX_STAT_AC_COUNT 22 | 5008 | #define EMAC_REG_EMAC_TX_STAT_AC_COUNT 22 |
5009 | #define EMAC_REG_RX_PFC_MODE 0x320 | ||
5010 | #define EMAC_REG_RX_PFC_MODE_PRIORITIES (1L<<2) | ||
5011 | #define EMAC_REG_RX_PFC_MODE_RX_EN (1L<<1) | ||
5012 | #define EMAC_REG_RX_PFC_MODE_TX_EN (1L<<0) | ||
5013 | #define EMAC_REG_RX_PFC_PARAM 0x324 | ||
5014 | #define EMAC_REG_RX_PFC_PARAM_OPCODE_BITSHIFT 0 | ||
5015 | #define EMAC_REG_RX_PFC_PARAM_PRIORITY_EN_BITSHIFT 16 | ||
5016 | #define EMAC_REG_RX_PFC_STATS_XOFF_RCVD 0x328 | ||
5017 | #define EMAC_REG_RX_PFC_STATS_XOFF_RCVD_COUNT (0xffff<<0) | ||
5018 | #define EMAC_REG_RX_PFC_STATS_XOFF_SENT 0x330 | ||
5019 | #define EMAC_REG_RX_PFC_STATS_XOFF_SENT_COUNT (0xffff<<0) | ||
5020 | #define EMAC_REG_RX_PFC_STATS_XON_RCVD 0x32c | ||
5021 | #define EMAC_REG_RX_PFC_STATS_XON_RCVD_COUNT (0xffff<<0) | ||
5022 | #define EMAC_REG_RX_PFC_STATS_XON_SENT 0x334 | ||
5023 | #define EMAC_REG_RX_PFC_STATS_XON_SENT_COUNT (0xffff<<0) | ||
4978 | #define EMAC_RX_MODE_FLOW_EN (1L<<2) | 5024 | #define EMAC_RX_MODE_FLOW_EN (1L<<2) |
5025 | #define EMAC_RX_MODE_KEEP_MAC_CONTROL (1L<<3) | ||
4979 | #define EMAC_RX_MODE_KEEP_VLAN_TAG (1L<<10) | 5026 | #define EMAC_RX_MODE_KEEP_VLAN_TAG (1L<<10) |
4980 | #define EMAC_RX_MODE_PROMISCUOUS (1L<<8) | 5027 | #define EMAC_RX_MODE_PROMISCUOUS (1L<<8) |
4981 | #define EMAC_RX_MODE_RESET (1L<<0) | 5028 | #define EMAC_RX_MODE_RESET (1L<<0) |