aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Fastabend <john.r.fastabend@intel.com>2011-03-01 00:25:35 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2011-03-12 07:10:31 -0500
commit3032309b49622497430ecd2b40ff51fb204c35e8 (patch)
tree766e78c2334148421c80a213cecab5e4fe546da1
parent0d1fe82deacdcc90458558b5d6a4a5af5db9a6c6 (diff)
ixgbe: DCB, implement capabilities flags
This implements dcbnl get and set capabilities ops. The devices supported by ixgbe can be configured to run in IEEE or CEE modes but not both. With the DCBX set capabilities bit we add an explicit signal that must be used to toggle between these modes. This patch adds logic to fail the CEE command set_hw_all() which programs the device with a CEE configuration if the CEE caps bit is not set. Similarly, IEEE set commands will fail if the IEEE caps bit is not set. We allow most CEE config set commands to occur because they do not touch the hardware until set_hw_all() is called. The one exception to the above is the {set|get}app routines. These must always be protected by caps bits to ensure side effects do not corrupt the current configured mode. By requiring the caps bit to be set correctly we can maintain a consistent configuration in the hardware for CEE or IEEE modes and prevent partial hardware configurations that may occur if user space does not send a complete IEEE or CEE configurations. It is expected that user space will signal a DCBX mode before programming device. Signed-off-by: John Fastabend <john.r.fastabend@intel.com> Tested-by: Ross Brattain <ross.b.brattain@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r--drivers/net/ixgbe/ixgbe.h1
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_nl.c129
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c1
3 files changed, 95 insertions, 36 deletions
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index 1e546fc127d0..815edfd7d0ee 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -341,6 +341,7 @@ struct ixgbe_adapter {
341 struct ixgbe_dcb_config dcb_cfg; 341 struct ixgbe_dcb_config dcb_cfg;
342 struct ixgbe_dcb_config temp_dcb_cfg; 342 struct ixgbe_dcb_config temp_dcb_cfg;
343 u8 dcb_set_bitmap; 343 u8 dcb_set_bitmap;
344 u8 dcbx_cap;
344 enum ixgbe_fc_mode last_lfc_mode; 345 enum ixgbe_fc_mode last_lfc_mode;
345 346
346 /* Interrupt Throttle Rate */ 347 /* Interrupt Throttle Rate */
diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c
index d7f0024014b1..d7c456f685ff 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_nl.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c
@@ -346,7 +346,8 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
346 struct ixgbe_adapter *adapter = netdev_priv(netdev); 346 struct ixgbe_adapter *adapter = netdev_priv(netdev);
347 int ret; 347 int ret;
348 348
349 if (!adapter->dcb_set_bitmap) 349 if (!adapter->dcb_set_bitmap ||
350 !(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
350 return DCB_NO_HW_CHG; 351 return DCB_NO_HW_CHG;
351 352
352 ret = ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg, &adapter->dcb_cfg, 353 ret = ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg, &adapter->dcb_cfg,
@@ -448,40 +449,38 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
448static u8 ixgbe_dcbnl_getcap(struct net_device *netdev, int capid, u8 *cap) 449static u8 ixgbe_dcbnl_getcap(struct net_device *netdev, int capid, u8 *cap)
449{ 450{
450 struct ixgbe_adapter *adapter = netdev_priv(netdev); 451 struct ixgbe_adapter *adapter = netdev_priv(netdev);
451 u8 rval = 0;
452 452
453 if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { 453 switch (capid) {
454 switch (capid) { 454 case DCB_CAP_ATTR_PG:
455 case DCB_CAP_ATTR_PG: 455 *cap = true;
456 *cap = true; 456 break;
457 break; 457 case DCB_CAP_ATTR_PFC:
458 case DCB_CAP_ATTR_PFC: 458 *cap = true;
459 *cap = true; 459 break;
460 break; 460 case DCB_CAP_ATTR_UP2TC:
461 case DCB_CAP_ATTR_UP2TC: 461 *cap = false;
462 *cap = false; 462 break;
463 break; 463 case DCB_CAP_ATTR_PG_TCS:
464 case DCB_CAP_ATTR_PG_TCS: 464 *cap = 0x80;
465 *cap = 0x80; 465 break;
466 break; 466 case DCB_CAP_ATTR_PFC_TCS:
467 case DCB_CAP_ATTR_PFC_TCS: 467 *cap = 0x80;
468 *cap = 0x80; 468 break;
469 break; 469 case DCB_CAP_ATTR_GSP:
470 case DCB_CAP_ATTR_GSP: 470 *cap = true;
471 *cap = true; 471 break;
472 break; 472 case DCB_CAP_ATTR_BCN:
473 case DCB_CAP_ATTR_BCN: 473 *cap = false;
474 *cap = false; 474 break;
475 break; 475 case DCB_CAP_ATTR_DCBX:
476 default: 476 *cap = adapter->dcbx_cap;
477 rval = -EINVAL; 477 break;
478 break; 478 default:
479 } 479 *cap = false;
480 } else { 480 break;
481 rval = -EINVAL;
482 } 481 }
483 482
484 return rval; 483 return 0;
485} 484}
486 485
487static u8 ixgbe_dcbnl_getnumtcs(struct net_device *netdev, int tcid, u8 *num) 486static u8 ixgbe_dcbnl_getnumtcs(struct net_device *netdev, int tcid, u8 *num)
@@ -542,13 +541,17 @@ static void ixgbe_dcbnl_setpfcstate(struct net_device *netdev, u8 state)
542 */ 541 */
543static u8 ixgbe_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id) 542static u8 ixgbe_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id)
544{ 543{
544 struct ixgbe_adapter *adapter = netdev_priv(netdev);
545 u8 rval = 0; 545 u8 rval = 0;
546 546
547 if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
548 return rval;
549
547 switch (idtype) { 550 switch (idtype) {
548 case DCB_APP_IDTYPE_ETHTYPE: 551 case DCB_APP_IDTYPE_ETHTYPE:
549#ifdef IXGBE_FCOE 552#ifdef IXGBE_FCOE
550 if (id == ETH_P_FCOE) 553 if (id == ETH_P_FCOE)
551 rval = ixgbe_fcoe_getapp(netdev_priv(netdev)); 554 rval = ixgbe_fcoe_getapp(adapter);
552#endif 555#endif
553 break; 556 break;
554 case DCB_APP_IDTYPE_PORTNUM: 557 case DCB_APP_IDTYPE_PORTNUM:
@@ -571,14 +574,17 @@ static u8 ixgbe_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id)
571static u8 ixgbe_dcbnl_setapp(struct net_device *netdev, 574static u8 ixgbe_dcbnl_setapp(struct net_device *netdev,
572 u8 idtype, u16 id, u8 up) 575 u8 idtype, u16 id, u8 up)
573{ 576{
577 struct ixgbe_adapter *adapter = netdev_priv(netdev);
574 u8 rval = 1; 578 u8 rval = 1;
575 579
580 if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
581 return rval;
582
576 switch (idtype) { 583 switch (idtype) {
577 case DCB_APP_IDTYPE_ETHTYPE: 584 case DCB_APP_IDTYPE_ETHTYPE:
578#ifdef IXGBE_FCOE 585#ifdef IXGBE_FCOE
579 if (id == ETH_P_FCOE) { 586 if (id == ETH_P_FCOE) {
580 u8 old_tc; 587 u8 old_tc;
581 struct ixgbe_adapter *adapter = netdev_priv(netdev);
582 588
583 /* Get current programmed tc */ 589 /* Get current programmed tc */
584 old_tc = adapter->fcoe.tc; 590 old_tc = adapter->fcoe.tc;
@@ -640,6 +646,9 @@ static int ixgbe_dcbnl_ieee_setets(struct net_device *dev,
640 /* naively give each TC a bwg to map onto CEE hardware */ 646 /* naively give each TC a bwg to map onto CEE hardware */
641 __u8 bwg_id[IEEE_8021QAZ_MAX_TCS] = {0, 1, 2, 3, 4, 5, 6, 7}; 647 __u8 bwg_id[IEEE_8021QAZ_MAX_TCS] = {0, 1, 2, 3, 4, 5, 6, 7};
642 648
649 if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
650 return -EINVAL;
651
643 if (!adapter->ixgbe_ieee_ets) { 652 if (!adapter->ixgbe_ieee_ets) {
644 adapter->ixgbe_ieee_ets = kmalloc(sizeof(struct ieee_ets), 653 adapter->ixgbe_ieee_ets = kmalloc(sizeof(struct ieee_ets),
645 GFP_KERNEL); 654 GFP_KERNEL);
@@ -647,7 +656,6 @@ static int ixgbe_dcbnl_ieee_setets(struct net_device *dev,
647 return -ENOMEM; 656 return -ENOMEM;
648 } 657 }
649 658
650
651 memcpy(adapter->ixgbe_ieee_ets, ets, sizeof(*adapter->ixgbe_ieee_ets)); 659 memcpy(adapter->ixgbe_ieee_ets, ets, sizeof(*adapter->ixgbe_ieee_ets));
652 660
653 ixgbe_ieee_credits(ets->tc_tx_bw, refill, max, max_frame); 661 ixgbe_ieee_credits(ets->tc_tx_bw, refill, max, max_frame);
@@ -686,6 +694,9 @@ static int ixgbe_dcbnl_ieee_setpfc(struct net_device *dev,
686 struct ixgbe_adapter *adapter = netdev_priv(dev); 694 struct ixgbe_adapter *adapter = netdev_priv(dev);
687 int err; 695 int err;
688 696
697 if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
698 return -EINVAL;
699
689 if (!adapter->ixgbe_ieee_pfc) { 700 if (!adapter->ixgbe_ieee_pfc) {
690 adapter->ixgbe_ieee_pfc = kmalloc(sizeof(struct ieee_pfc), 701 adapter->ixgbe_ieee_pfc = kmalloc(sizeof(struct ieee_pfc),
691 GFP_KERNEL); 702 GFP_KERNEL);
@@ -698,6 +709,51 @@ static int ixgbe_dcbnl_ieee_setpfc(struct net_device *dev,
698 return err; 709 return err;
699} 710}
700 711
712static u8 ixgbe_dcbnl_getdcbx(struct net_device *dev)
713{
714 struct ixgbe_adapter *adapter = netdev_priv(dev);
715 return adapter->dcbx_cap;
716}
717
718static u8 ixgbe_dcbnl_setdcbx(struct net_device *dev, u8 mode)
719{
720 struct ixgbe_adapter *adapter = netdev_priv(dev);
721 struct ieee_ets ets = {0};
722 struct ieee_pfc pfc = {0};
723
724 /* no support for LLD_MANAGED modes or CEE+IEEE */
725 if ((mode & DCB_CAP_DCBX_LLD_MANAGED) ||
726 ((mode & DCB_CAP_DCBX_VER_IEEE) && (mode & DCB_CAP_DCBX_VER_CEE)) ||
727 !(mode & DCB_CAP_DCBX_HOST))
728 return 1;
729
730 if (mode == adapter->dcbx_cap)
731 return 0;
732
733 adapter->dcbx_cap = mode;
734
735 /* ETS and PFC defaults */
736 ets.ets_cap = 8;
737 pfc.pfc_cap = 8;
738
739 if (mode & DCB_CAP_DCBX_VER_IEEE) {
740 ixgbe_dcbnl_ieee_setets(dev, &ets);
741 ixgbe_dcbnl_ieee_setpfc(dev, &pfc);
742 } else if (mode & DCB_CAP_DCBX_VER_CEE) {
743 adapter->dcb_set_bitmap |= (BIT_PFC & BIT_PG_TX & BIT_PG_RX);
744 ixgbe_dcbnl_set_all(dev);
745 } else {
746 /* Drop into single TC mode strict priority as this
747 * indicates CEE and IEEE versions are disabled
748 */
749 ixgbe_dcbnl_ieee_setets(dev, &ets);
750 ixgbe_dcbnl_ieee_setpfc(dev, &pfc);
751 ixgbe_dcbnl_set_state(dev, 0);
752 }
753
754 return 0;
755}
756
701const struct dcbnl_rtnl_ops dcbnl_ops = { 757const struct dcbnl_rtnl_ops dcbnl_ops = {
702 .ieee_getets = ixgbe_dcbnl_ieee_getets, 758 .ieee_getets = ixgbe_dcbnl_ieee_getets,
703 .ieee_setets = ixgbe_dcbnl_ieee_setets, 759 .ieee_setets = ixgbe_dcbnl_ieee_setets,
@@ -724,5 +780,6 @@ const struct dcbnl_rtnl_ops dcbnl_ops = {
724 .setpfcstate = ixgbe_dcbnl_setpfcstate, 780 .setpfcstate = ixgbe_dcbnl_setpfcstate,
725 .getapp = ixgbe_dcbnl_getapp, 781 .getapp = ixgbe_dcbnl_getapp,
726 .setapp = ixgbe_dcbnl_setapp, 782 .setapp = ixgbe_dcbnl_setapp,
783 .getdcbx = ixgbe_dcbnl_getdcbx,
784 .setdcbx = ixgbe_dcbnl_setdcbx,
727}; 785};
728
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 5998dc94dd5c..4aeade82812a 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -5190,6 +5190,7 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
5190 adapter->dcb_cfg.rx_pba_cfg = pba_equal; 5190 adapter->dcb_cfg.rx_pba_cfg = pba_equal;
5191 adapter->dcb_cfg.pfc_mode_enable = false; 5191 adapter->dcb_cfg.pfc_mode_enable = false;
5192 adapter->dcb_set_bitmap = 0x00; 5192 adapter->dcb_set_bitmap = 0x00;
5193 adapter->dcbx_cap = DCB_CAP_DCBX_HOST | DCB_CAP_DCBX_VER_CEE;
5193 ixgbe_copy_dcb_cfg(&adapter->dcb_cfg, &adapter->temp_dcb_cfg, 5194 ixgbe_copy_dcb_cfg(&adapter->dcb_cfg, &adapter->temp_dcb_cfg,
5194 adapter->ring_feature[RING_F_DCB].indices); 5195 adapter->ring_feature[RING_F_DCB].indices);
5195 5196