diff options
-rw-r--r-- | include/linux/dcbnl.h | 23 | ||||
-rw-r--r-- | net/dcb/dcbnl.c | 159 |
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 | */ |
343 | enum cee_attrs { | 350 | enum 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 | ||
372 | enum 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 | ||
1645 | static 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 | |||
1695 | nla_put_failure: | ||
1696 | return -EMSGSIZE; | ||
1697 | } | ||
1698 | |||
1645 | /* Handle CEE DCBX GET commands. */ | 1699 | /* Handle CEE DCBX GET commands. */ |
1646 | static int dcbnl_cee_get(struct net_device *netdev, struct nlattr **tb, | 1700 | static 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 | |||
1846 | dcb_unlock: | ||
1847 | spin_unlock(&dcb_lock); | ||
1703 | nla_put_failure: | 1848 | nla_put_failure: |
1704 | nlmsg_cancel(skb, nlh); | 1849 | nlmsg_cancel(skb, nlh); |
1705 | nlmsg_failure: | 1850 | nlmsg_failure: |
1706 | kfree_skb(skb); | 1851 | nlmsg_free(skb); |
1707 | return -1; | 1852 | return err; |
1708 | } | 1853 | } |
1709 | 1854 | ||
1710 | static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 1855 | static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) |