aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/dcbnl.h23
-rw-r--r--net/dcb/dcbnl.c159
2 files changed, 173 insertions, 9 deletions
diff --git a/include/linux/dcbnl.h b/include/linux/dcbnl.h
index 66a67235e729..65a2562f66b4 100644
--- a/include/linux/dcbnl.h
+++ b/include/linux/dcbnl.h
@@ -333,18 +333,30 @@ enum ieee_attrs_app {
333#define DCB_ATTR_IEEE_APP_MAX (__DCB_ATTR_IEEE_APP_MAX - 1) 333#define DCB_ATTR_IEEE_APP_MAX (__DCB_ATTR_IEEE_APP_MAX - 1)
334 334
335/** 335/**
336 * enum cee_attrs - CEE DCBX get attributes 336 * enum cee_attrs - CEE DCBX get attributes.
337 * 337 *
338 * @DCB_ATTR_CEE_UNSPEC: unspecified 338 * @DCB_ATTR_CEE_UNSPEC: unspecified
339 * @DCB_ATTR_CEE_PEER_PG: peer PG configuration - get only 339 * @DCB_ATTR_CEE_PEER_PG: peer PG configuration - get only
340 * @DCB_ATTR_CEE_PEER_PFC: peer PFC configuration - get only 340 * @DCB_ATTR_CEE_PEER_PFC: peer PFC configuration - get only
341 * @DCB_ATTR_CEE_PEER_APP: peer APP tlv - get only 341 * @DCB_ATTR_CEE_PEER_APP_TABLE: peer APP tlv - get only
342 * @DCB_ATTR_CEE_TX_PG: TX PG configuration (DCB_CMD_PGTX_GCFG)
343 * @DCB_ATTR_CEE_RX_PG: RX PG configuration (DCB_CMD_PGRX_GCFG)
344 * @DCB_ATTR_CEE_PFC: PFC configuration (DCB_CMD_PFC_GCFG)
345 * @DCB_ATTR_CEE_APP_TABLE: APP configuration (multi DCB_CMD_GAPP)
346 * @DCB_ATTR_CEE_FEAT: DCBX features flags (DCB_CMD_GFEATCFG)
347 *
348 * An aggregated collection of the cee std negotiated parameters.
342 */ 349 */
343enum cee_attrs { 350enum cee_attrs {
344 DCB_ATTR_CEE_UNSPEC, 351 DCB_ATTR_CEE_UNSPEC,
345 DCB_ATTR_CEE_PEER_PG, 352 DCB_ATTR_CEE_PEER_PG,
346 DCB_ATTR_CEE_PEER_PFC, 353 DCB_ATTR_CEE_PEER_PFC,
347 DCB_ATTR_CEE_PEER_APP_TABLE, 354 DCB_ATTR_CEE_PEER_APP_TABLE,
355 DCB_ATTR_CEE_TX_PG,
356 DCB_ATTR_CEE_RX_PG,
357 DCB_ATTR_CEE_PFC,
358 DCB_ATTR_CEE_APP_TABLE,
359 DCB_ATTR_CEE_FEAT,
348 __DCB_ATTR_CEE_MAX 360 __DCB_ATTR_CEE_MAX
349}; 361};
350#define DCB_ATTR_CEE_MAX (__DCB_ATTR_CEE_MAX - 1) 362#define DCB_ATTR_CEE_MAX (__DCB_ATTR_CEE_MAX - 1)
@@ -357,6 +369,13 @@ enum peer_app_attr {
357}; 369};
358#define DCB_ATTR_CEE_PEER_APP_MAX (__DCB_ATTR_CEE_PEER_APP_MAX - 1) 370#define DCB_ATTR_CEE_PEER_APP_MAX (__DCB_ATTR_CEE_PEER_APP_MAX - 1)
359 371
372enum cee_attrs_app {
373 DCB_ATTR_CEE_APP_UNSPEC,
374 DCB_ATTR_CEE_APP,
375 __DCB_ATTR_CEE_APP_MAX
376};
377#define DCB_ATTR_CEE_APP_MAX (__DCB_ATTR_CEE_APP_MAX - 1)
378
360/** 379/**
361 * enum dcbnl_pfc_attrs - DCB Priority Flow Control user priority nested attrs 380 * enum dcbnl_pfc_attrs - DCB Priority Flow Control user priority nested attrs
362 * 381 *
diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c
index fc56e8546261..d5b45a201c1b 100644
--- a/net/dcb/dcbnl.c
+++ b/net/dcb/dcbnl.c
@@ -1642,6 +1642,60 @@ err:
1642 return ret; 1642 return ret;
1643} 1643}
1644 1644
1645static int dcbnl_cee_pg_fill(struct sk_buff *skb, struct net_device *dev,
1646 int dir)
1647{
1648 u8 pgid, up_map, prio, tc_pct;
1649 const struct dcbnl_rtnl_ops *ops = dev->dcbnl_ops;
1650 int i = dir ? DCB_ATTR_CEE_TX_PG : DCB_ATTR_CEE_RX_PG;
1651 struct nlattr *pg = nla_nest_start(skb, i);
1652
1653 if (!pg)
1654 goto nla_put_failure;
1655
1656 for (i = DCB_PG_ATTR_TC_0; i <= DCB_PG_ATTR_TC_7; i++) {
1657 struct nlattr *tc_nest = nla_nest_start(skb, i);
1658
1659 if (!tc_nest)
1660 goto nla_put_failure;
1661
1662 pgid = DCB_ATTR_VALUE_UNDEFINED;
1663 prio = DCB_ATTR_VALUE_UNDEFINED;
1664 tc_pct = DCB_ATTR_VALUE_UNDEFINED;
1665 up_map = DCB_ATTR_VALUE_UNDEFINED;
1666
1667 if (!dir)
1668 ops->getpgtccfgrx(dev, i - DCB_PG_ATTR_TC_0,
1669 &prio, &pgid, &tc_pct, &up_map);
1670 else
1671 ops->getpgtccfgtx(dev, i - DCB_PG_ATTR_TC_0,
1672 &prio, &pgid, &tc_pct, &up_map);
1673
1674 NLA_PUT_U8(skb, DCB_TC_ATTR_PARAM_PGID, pgid);
1675 NLA_PUT_U8(skb, DCB_TC_ATTR_PARAM_UP_MAPPING, up_map);
1676 NLA_PUT_U8(skb, DCB_TC_ATTR_PARAM_STRICT_PRIO, prio);
1677 NLA_PUT_U8(skb, DCB_TC_ATTR_PARAM_BW_PCT, tc_pct);
1678 nla_nest_end(skb, tc_nest);
1679 }
1680
1681 for (i = DCB_PG_ATTR_BW_ID_0; i <= DCB_PG_ATTR_BW_ID_7; i++) {
1682 tc_pct = DCB_ATTR_VALUE_UNDEFINED;
1683
1684 if (!dir)
1685 ops->getpgbwgcfgrx(dev, i - DCB_PG_ATTR_BW_ID_0,
1686 &tc_pct);
1687 else
1688 ops->getpgbwgcfgtx(dev, i - DCB_PG_ATTR_BW_ID_0,
1689 &tc_pct);
1690 NLA_PUT_U8(skb, i, tc_pct);
1691 }
1692 nla_nest_end(skb, pg);
1693 return 0;
1694
1695nla_put_failure:
1696 return -EMSGSIZE;
1697}
1698
1645/* Handle CEE DCBX GET commands. */ 1699/* Handle CEE DCBX GET commands. */
1646static int dcbnl_cee_get(struct net_device *netdev, struct nlattr **tb, 1700static int dcbnl_cee_get(struct net_device *netdev, struct nlattr **tb,
1647 u32 pid, u32 seq, u16 flags) 1701 u32 pid, u32 seq, u16 flags)
@@ -1649,9 +1703,11 @@ static int dcbnl_cee_get(struct net_device *netdev, struct nlattr **tb,
1649 struct sk_buff *skb; 1703 struct sk_buff *skb;
1650 struct nlmsghdr *nlh; 1704 struct nlmsghdr *nlh;
1651 struct dcbmsg *dcb; 1705 struct dcbmsg *dcb;
1652 struct nlattr *cee; 1706 struct nlattr *cee, *app;
1707 struct dcb_app_type *itr;
1653 const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 1708 const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops;
1654 int err; 1709 int dcbx, i, err = -EMSGSIZE;
1710 u8 value;
1655 1711
1656 if (!ops) 1712 if (!ops)
1657 return -EOPNOTSUPP; 1713 return -EOPNOTSUPP;
@@ -1672,7 +1728,88 @@ static int dcbnl_cee_get(struct net_device *netdev, struct nlattr **tb,
1672 if (!cee) 1728 if (!cee)
1673 goto nla_put_failure; 1729 goto nla_put_failure;
1674 1730
1675 /* get peer info if available */ 1731 /* local pg */
1732 if (ops->getpgtccfgtx && ops->getpgbwgcfgtx) {
1733 err = dcbnl_cee_pg_fill(skb, netdev, 1);
1734 if (err)
1735 goto nla_put_failure;
1736 }
1737
1738 if (ops->getpgtccfgrx && ops->getpgbwgcfgrx) {
1739 err = dcbnl_cee_pg_fill(skb, netdev, 0);
1740 if (err)
1741 goto nla_put_failure;
1742 }
1743
1744 /* local pfc */
1745 if (ops->getpfccfg) {
1746 struct nlattr *pfc_nest = nla_nest_start(skb, DCB_ATTR_CEE_PFC);
1747
1748 if (!pfc_nest)
1749 goto nla_put_failure;
1750
1751 for (i = DCB_PFC_UP_ATTR_0; i <= DCB_PFC_UP_ATTR_7; i++) {
1752 ops->getpfccfg(netdev, i - DCB_PFC_UP_ATTR_0, &value);
1753 NLA_PUT_U8(skb, i, value);
1754 }
1755 nla_nest_end(skb, pfc_nest);
1756 }
1757
1758 /* local app */
1759 spin_lock(&dcb_lock);
1760 app = nla_nest_start(skb, DCB_ATTR_CEE_APP_TABLE);
1761 if (!app)
1762 goto nla_put_failure;
1763
1764 list_for_each_entry(itr, &dcb_app_list, list) {
1765 if (strncmp(itr->name, netdev->name, IFNAMSIZ) == 0) {
1766 struct nlattr *app_nest = nla_nest_start(skb,
1767 DCB_ATTR_APP);
1768 if (!app_nest)
1769 goto dcb_unlock;
1770
1771 err = nla_put_u8(skb, DCB_APP_ATTR_IDTYPE,
1772 itr->app.selector);
1773 if (err)
1774 goto dcb_unlock;
1775
1776 err = nla_put_u16(skb, DCB_APP_ATTR_ID,
1777 itr->app.protocol);
1778 if (err)
1779 goto dcb_unlock;
1780
1781 err = nla_put_u8(skb, DCB_APP_ATTR_PRIORITY,
1782 itr->app.priority);
1783 if (err)
1784 goto dcb_unlock;
1785
1786 nla_nest_end(skb, app_nest);
1787 }
1788 }
1789 nla_nest_end(skb, app);
1790
1791 if (netdev->dcbnl_ops->getdcbx)
1792 dcbx = netdev->dcbnl_ops->getdcbx(netdev);
1793 else
1794 dcbx = -EOPNOTSUPP;
1795
1796 spin_unlock(&dcb_lock);
1797
1798 /* features flags */
1799 if (ops->getfeatcfg) {
1800 struct nlattr *feat = nla_nest_start(skb, DCB_ATTR_CEE_FEAT);
1801 if (!feat)
1802 goto nla_put_failure;
1803
1804 for (i = DCB_FEATCFG_ATTR_ALL + 1; i <= DCB_FEATCFG_ATTR_MAX;
1805 i++)
1806 if (!ops->getfeatcfg(netdev, i, &value))
1807 NLA_PUT_U8(skb, i, value);
1808
1809 nla_nest_end(skb, feat);
1810 }
1811
1812 /* peer info if available */
1676 if (ops->cee_peer_getpg) { 1813 if (ops->cee_peer_getpg) {
1677 struct cee_pg pg; 1814 struct cee_pg pg;
1678 err = ops->cee_peer_getpg(netdev, &pg); 1815 err = ops->cee_peer_getpg(netdev, &pg);
@@ -1695,16 +1832,24 @@ static int dcbnl_cee_get(struct net_device *netdev, struct nlattr **tb,
1695 if (err) 1832 if (err)
1696 goto nla_put_failure; 1833 goto nla_put_failure;
1697 } 1834 }
1698
1699 nla_nest_end(skb, cee); 1835 nla_nest_end(skb, cee);
1700 nlmsg_end(skb, nlh);
1701 1836
1837 /* DCBX state */
1838 if (dcbx >= 0) {
1839 err = nla_put_u8(skb, DCB_ATTR_DCBX, dcbx);
1840 if (err)
1841 goto nla_put_failure;
1842 }
1843 nlmsg_end(skb, nlh);
1702 return rtnl_unicast(skb, &init_net, pid); 1844 return rtnl_unicast(skb, &init_net, pid);
1845
1846dcb_unlock:
1847 spin_unlock(&dcb_lock);
1703nla_put_failure: 1848nla_put_failure:
1704 nlmsg_cancel(skb, nlh); 1849 nlmsg_cancel(skb, nlh);
1705nlmsg_failure: 1850nlmsg_failure:
1706 kfree_skb(skb); 1851 nlmsg_free(skb);
1707 return -1; 1852 return err;
1708} 1853}
1709 1854
1710static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) 1855static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)