... | ... | ||
---|---|---|---|
76 | - Renamed attributes from DCB_ATTR_IEEE_* to DCB_ATTR_DCB_*. | 76 | - Renamed attributes from DCB_ATTR_IEEE_* to DCB_ATTR_DCB_*. |
77 | - Renamed ieee_set/getapptrust to dcbnl_set/getapptrust. | 77 | - Renamed ieee_set/getapptrust to dcbnl_set/getapptrust. |
78 | - Added -EOPNOTSUPP if dcbnl_setapptrust is not set. | 78 | - Added -EOPNOTSUPP if dcbnl_setapptrust is not set. |
79 | - Added sanitization of selector array, before passing to driver. | 79 | - Added sanitization of selector array, before passing to driver. |
80 | 80 | ||
81 | RFC v2 -> (non-RFC) v1 | 81 | RFC v2 -> (non-RFC) v1: |
82 | - Added additional check for selector validity. | 82 | - Added additional check for selector validity. |
83 | - Fixed a few style errors. | 83 | - Fixed a few style errors. |
84 | - using nla_start_nest() instead of nla_start_nest_no_flag(). | 84 | - using nla_start_nest() instead of nla_start_nest_no_flag(). |
85 | - Moved DCB_ATTR_DCB_APP_TRUST into new enum. | 85 | - Moved DCB_ATTR_DCB_APP_TRUST into new enum. |
86 | - Added new DCB_ATTR_DCB_APP extension attribute, for non-std selector | 86 | - Added new DCB_ATTR_DCB_APP extension attribute, for non-std selector |
87 | values. | 87 | values. |
88 | - Added support for offloading dscp, pcp and default prio in the sparx5 | 88 | - Added support for offloading dscp, pcp and default prio in the sparx5 |
89 | driver. | 89 | driver. |
90 | - Added support for per-selector trust and trust order in the sparx5 | 90 | - Added support for per-selector trust and trust order in the sparx5 |
91 | driver. | 91 | driver. |
92 | 92 | ||
93 | v1 -> v2 | 93 | v1 -> v2: |
94 | - Fixed compiler and kdoc warning | 94 | - Fixed compiler and kdoc warning |
95 | 95 | ||
96 | v2 -> v3 | 96 | v2 -> v3: |
97 | - Moved back to 255 as PCP selector value. | 97 | - Moved back to 255 as PCP selector value. |
98 | - Fixed return value in dcbnl_app_attr_type_get() to enum. | 98 | - Fixed return value in dcbnl_app_attr_type_get() to enum. |
99 | - Modified in dcbnl_app_attr_type_get() dcbnl_app_attr_type_validate() to | 99 | - Modified in dcbnl_app_attr_type_get() dcbnl_app_attr_type_validate() to |
100 | return directly. | 100 | return directly. |
101 | - Added nselector check in sparx5_dcb_apptrust_validate(). | 101 | - Added nselector check in sparx5_dcb_apptrust_validate(). |
102 | - Added const qualifier to "names" variable in struct sparx5_dcb_apptrust. | 102 | - Added const qualifier to "names" variable in struct sparx5_dcb_apptrust. |
103 | - Added new SPARX5_DCB config. Fixes issues reported by kernel test robot. | 103 | - Added new SPARX5_DCB config. Fixes issues reported by kernel test robot. |
104 | |||
105 | v3 -> v4: | ||
106 | - Added new dcbnl_app_attr_selector_validate() function to validate that | ||
107 | app selectors are sent in correct attribute e.g IEEE selectors in | ||
108 | DCB_ATTR_IEEE and non-std selectors in DCB_ATTR_DCB. | ||
109 | - Modified handling of dcbnl_getapptrust() return value, so that an error is | ||
110 | ignored. Instead, added error check on nla_put_u8() and cancelling nest in | ||
111 | case of an error. | ||
104 | 112 | ||
105 | Daniel Machon (6): | 113 | Daniel Machon (6): |
106 | net: dcb: add new pcp selector to app object | 114 | net: dcb: add new pcp selector to app object |
107 | net: dcb: add new apptrust attribute | 115 | net: dcb: add new apptrust attribute |
108 | net: microchip: sparx5: add support for offloading pcp table | 116 | net: microchip: sparx5: add support for offloading pcp table |
109 | net: microchip: sparx5: add support for apptrust | 117 | net: microchip: sparx5: add support for apptrust |
110 | net: microchip: sparx5: add support for offloading dscp table | 118 | net: microchip: sparx5: add support for offloading dscp table |
111 | net: microchip: sparx5: add support for offloading default prio | 119 | net: microchip: sparx5: add support for offloading default prio |
112 | 120 | ||
113 | drivers/net/ethernet/microchip/sparx5/Kconfig | 8 + | 121 | drivers/net/ethernet/microchip/sparx5/Kconfig | 10 + |
114 | .../net/ethernet/microchip/sparx5/Makefile | 2 + | 122 | .../net/ethernet/microchip/sparx5/Makefile | 2 + |
115 | .../ethernet/microchip/sparx5/sparx5_dcb.c | 293 ++++++++++++++++++ | 123 | .../ethernet/microchip/sparx5/sparx5_dcb.c | 293 ++++++++++++++++++ |
116 | .../ethernet/microchip/sparx5/sparx5_main.h | 11 + | 124 | .../ethernet/microchip/sparx5/sparx5_main.h | 11 + |
117 | .../microchip/sparx5/sparx5_main_regs.h | 127 +++++++- | 125 | .../microchip/sparx5/sparx5_main_regs.h | 127 +++++++- |
118 | .../ethernet/microchip/sparx5/sparx5_port.c | 99 ++++++ | 126 | .../ethernet/microchip/sparx5/sparx5_port.c | 99 ++++++ |
119 | .../ethernet/microchip/sparx5/sparx5_port.h | 37 +++ | 127 | .../ethernet/microchip/sparx5/sparx5_port.h | 37 +++ |
120 | .../ethernet/microchip/sparx5/sparx5_qos.c | 4 + | 128 | .../ethernet/microchip/sparx5/sparx5_qos.c | 4 + |
121 | include/net/dcbnl.h | 4 + | 129 | include/net/dcbnl.h | 4 + |
122 | include/uapi/linux/dcbnl.h | 15 + | 130 | include/uapi/linux/dcbnl.h | 16 + |
123 | net/dcb/dcbnl.c | 113 ++++++- | 131 | net/dcb/dcbnl.c | 159 +++++++++- |
124 | 11 files changed, 703 insertions(+), 10 deletions(-) | 132 | 11 files changed, 753 insertions(+), 9 deletions(-) |
125 | create mode 100644 drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c | 133 | create mode 100644 drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c |
126 | 134 | ||
127 | -- | 135 | -- |
128 | 2.34.1 | 136 | 2.34.1 | diff view generated by jsdifflib |
... | ... | ||
---|---|---|---|
18 | PCP and DEI is encoded in the protocol field as 8*dei+pcp, so that a | 18 | PCP and DEI is encoded in the protocol field as 8*dei+pcp, so that a |
19 | mapping of PCP 2 and DEI 1 to priority 3 is encoded as {255, 10, 3}. | 19 | mapping of PCP 2 and DEI 1 to priority 3 is encoded as {255, 10, 3}. |
20 | 20 | ||
21 | Signed-off-by: Daniel Machon <daniel.machon@microchip.com> | 21 | Signed-off-by: Daniel Machon <daniel.machon@microchip.com> |
22 | --- | 22 | --- |
23 | include/uapi/linux/dcbnl.h | 6 ++++++ | 23 | include/uapi/linux/dcbnl.h | 6 ++++ |
24 | net/dcb/dcbnl.c | 36 ++++++++++++++++++++++++++++++++---- | 24 | net/dcb/dcbnl.c | 73 +++++++++++++++++++++++++++++++++++--- |
25 | 2 files changed, 38 insertions(+), 4 deletions(-) | 25 | 2 files changed, 75 insertions(+), 4 deletions(-) |
26 | 26 | ||
27 | diff --git a/include/uapi/linux/dcbnl.h b/include/uapi/linux/dcbnl.h | 27 | diff --git a/include/uapi/linux/dcbnl.h b/include/uapi/linux/dcbnl.h |
28 | index XXXXXXX..XXXXXXX 100644 | 28 | index XXXXXXX..XXXXXXX 100644 |
29 | --- a/include/uapi/linux/dcbnl.h | 29 | --- a/include/uapi/linux/dcbnl.h |
30 | +++ b/include/uapi/linux/dcbnl.h | 30 | +++ b/include/uapi/linux/dcbnl.h |
... | ... | ||
88 | + default: | 88 | + default: |
89 | + return false; | 89 | + return false; |
90 | + } | 90 | + } |
91 | +} | 91 | +} |
92 | + | 92 | + |
93 | +static bool dcbnl_app_selector_validate(enum ieee_attrs_app type, u32 selector) | ||
94 | +{ | ||
95 | + switch (selector) { | ||
96 | + case IEEE_8021QAZ_APP_SEL_ETHERTYPE: | ||
97 | + case IEEE_8021QAZ_APP_SEL_STREAM: | ||
98 | + case IEEE_8021QAZ_APP_SEL_DGRAM: | ||
99 | + case IEEE_8021QAZ_APP_SEL_ANY: | ||
100 | + case IEEE_8021QAZ_APP_SEL_DSCP: | ||
101 | + /* IEEE std selectors in IEEE std attribute */ | ||
102 | + if (type == DCB_ATTR_IEEE_APP) | ||
103 | + return true; | ||
104 | + else | ||
105 | + return false; | ||
106 | + case DCB_APP_SEL_PCP: | ||
107 | + /* Non-std selectors in non-std attribute */ | ||
108 | + if (type == DCB_ATTR_DCB_APP) | ||
109 | + return true; | ||
110 | + else | ||
111 | + return false; | ||
112 | + default: | ||
113 | + return false; | ||
114 | + } | ||
115 | +} | ||
116 | + | ||
93 | static struct sk_buff *dcbnl_newmsg(int type, u8 cmd, u32 port, u32 seq, | 117 | static struct sk_buff *dcbnl_newmsg(int type, u8 cmd, u32 port, u32 seq, |
94 | u32 flags, struct nlmsghdr **nlhp) | 118 | u32 flags, struct nlmsghdr **nlhp) |
95 | { | 119 | { |
96 | @@ -XXX,XX +XXX,XX @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev) | 120 | @@ -XXX,XX +XXX,XX @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev) |
97 | spin_lock_bh(&dcb_lock); | 121 | spin_lock_bh(&dcb_lock); |
... | ... | ||
104 | + err = nla_put(skb, type, sizeof(itr->app), &itr->app); | 128 | + err = nla_put(skb, type, sizeof(itr->app), &itr->app); |
105 | if (err) { | 129 | if (err) { |
106 | spin_unlock_bh(&dcb_lock); | 130 | spin_unlock_bh(&dcb_lock); |
107 | return -EMSGSIZE; | 131 | return -EMSGSIZE; |
108 | @@ -XXX,XX +XXX,XX @@ static int dcbnl_ieee_set(struct net_device *netdev, struct nlmsghdr *nlh, | 132 | @@ -XXX,XX +XXX,XX @@ static int dcbnl_ieee_set(struct net_device *netdev, struct nlmsghdr *nlh, |
133 | int rem; | ||
134 | |||
109 | nla_for_each_nested(attr, ieee[DCB_ATTR_IEEE_APP_TABLE], rem) { | 135 | nla_for_each_nested(attr, ieee[DCB_ATTR_IEEE_APP_TABLE], rem) { |
136 | + enum ieee_attrs_app type = nla_type(attr); | ||
110 | struct dcb_app *app_data; | 137 | struct dcb_app *app_data; |
111 | 138 | ||
112 | - if (nla_type(attr) != DCB_ATTR_IEEE_APP) | 139 | - if (nla_type(attr) != DCB_ATTR_IEEE_APP) |
113 | + if (!dcbnl_app_attr_type_validate(nla_type(attr))) | 140 | + if (!dcbnl_app_attr_type_validate(type)) |
114 | continue; | 141 | continue; |
115 | 142 | ||
116 | if (nla_len(attr) < sizeof(struct dcb_app)) { | 143 | if (nla_len(attr) < sizeof(struct dcb_app)) { |
144 | @@ -XXX,XX +XXX,XX @@ static int dcbnl_ieee_set(struct net_device *netdev, struct nlmsghdr *nlh, | ||
145 | } | ||
146 | |||
147 | app_data = nla_data(attr); | ||
148 | + | ||
149 | + if (!dcbnl_app_selector_validate(type, | ||
150 | + app_data->selector)) | ||
151 | + return -EINVAL; | ||
152 | + | ||
153 | if (ops->ieee_setapp) | ||
154 | err = ops->ieee_setapp(netdev, app_data); | ||
155 | else | ||
117 | @@ -XXX,XX +XXX,XX @@ static int dcbnl_ieee_del(struct net_device *netdev, struct nlmsghdr *nlh, | 156 | @@ -XXX,XX +XXX,XX @@ static int dcbnl_ieee_del(struct net_device *netdev, struct nlmsghdr *nlh, |
157 | int rem; | ||
158 | |||
118 | nla_for_each_nested(attr, ieee[DCB_ATTR_IEEE_APP_TABLE], rem) { | 159 | nla_for_each_nested(attr, ieee[DCB_ATTR_IEEE_APP_TABLE], rem) { |
160 | + enum ieee_attrs_app type = nla_type(attr); | ||
119 | struct dcb_app *app_data; | 161 | struct dcb_app *app_data; |
120 | 162 | ||
121 | - if (nla_type(attr) != DCB_ATTR_IEEE_APP) | 163 | - if (nla_type(attr) != DCB_ATTR_IEEE_APP) |
122 | + if (!dcbnl_app_attr_type_validate(nla_type(attr))) | 164 | + if (!dcbnl_app_attr_type_validate(type)) |
123 | continue; | 165 | continue; |
166 | + | ||
124 | app_data = nla_data(attr); | 167 | app_data = nla_data(attr); |
168 | + | ||
169 | + if (!dcbnl_app_selector_validate(type, | ||
170 | + app_data->selector)) | ||
171 | + return -EINVAL; | ||
172 | + | ||
125 | if (ops->ieee_delapp) | 173 | if (ops->ieee_delapp) |
174 | err = ops->ieee_delapp(netdev, app_data); | ||
175 | else | ||
126 | -- | 176 | -- |
127 | 2.34.1 | 177 | 2.34.1 | diff view generated by jsdifflib |
... | ... | ||
---|---|---|---|
10 | 10 | ||
11 | Signed-off-by: Daniel Machon <daniel.machon@microchip.com> | 11 | Signed-off-by: Daniel Machon <daniel.machon@microchip.com> |
12 | --- | 12 | --- |
13 | include/net/dcbnl.h | 4 ++ | 13 | include/net/dcbnl.h | 4 ++ |
14 | include/uapi/linux/dcbnl.h | 10 +++++ | 14 | include/uapi/linux/dcbnl.h | 10 +++++ |
15 | net/dcb/dcbnl.c | 77 ++++++++++++++++++++++++++++++++++++-- | 15 | net/dcb/dcbnl.c | 78 +++++++++++++++++++++++++++++++++++++- |
16 | 3 files changed, 87 insertions(+), 4 deletions(-) | 16 | 3 files changed, 90 insertions(+), 2 deletions(-) |
17 | 17 | ||
18 | diff --git a/include/net/dcbnl.h b/include/net/dcbnl.h | 18 | diff --git a/include/net/dcbnl.h b/include/net/dcbnl.h |
19 | index XXXXXXX..XXXXXXX 100644 | 19 | index XXXXXXX..XXXXXXX 100644 |
20 | --- a/include/net/dcbnl.h | 20 | --- a/include/net/dcbnl.h |
21 | +++ b/include/net/dcbnl.h | 21 | +++ b/include/net/dcbnl.h |
... | ... | ||
84 | - struct nlattr *ieee, *app; | 84 | - struct nlattr *ieee, *app; |
85 | - struct dcb_app_type *itr; | 85 | - struct dcb_app_type *itr; |
86 | const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; | 86 | const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; |
87 | + struct nlattr *ieee, *app, *apptrust; | 87 | + struct nlattr *ieee, *app, *apptrust; |
88 | + struct dcb_app_type *itr; | 88 | + struct dcb_app_type *itr; |
89 | + int err, i; | ||
90 | int dcbx; | 89 | int dcbx; |
91 | - int err; | 90 | int err; |
92 | 91 | ||
93 | if (nla_put_string(skb, DCB_ATTR_IFNAME, netdev->name)) | ||
94 | return -EMSGSIZE; | ||
95 | @@ -XXX,XX +XXX,XX @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev) | 92 | @@ -XXX,XX +XXX,XX @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev) |
96 | spin_unlock_bh(&dcb_lock); | 93 | spin_unlock_bh(&dcb_lock); |
97 | nla_nest_end(skb, app); | 94 | nla_nest_end(skb, app); |
98 | 95 | ||
99 | + if (ops->dcbnl_getapptrust) { | 96 | + if (ops->dcbnl_getapptrust) { |
100 | + u8 selectors[IEEE_8021QAZ_APP_SEL_MAX + 1] = {0}; | 97 | + u8 selectors[IEEE_8021QAZ_APP_SEL_MAX + 1] = {0}; |
101 | + int nselectors; | 98 | + int nselectors, i; |
102 | + | 99 | + |
103 | + apptrust = nla_nest_start(skb, DCB_ATTR_DCB_APP_TRUST_TABLE); | 100 | + apptrust = nla_nest_start(skb, DCB_ATTR_DCB_APP_TRUST_TABLE); |
104 | + if (!app) | 101 | + if (!app) |
105 | + return -EMSGSIZE; | 102 | + return -EMSGSIZE; |
106 | + | 103 | + |
107 | + err = ops->dcbnl_getapptrust(netdev, selectors, &nselectors); | 104 | + err = ops->dcbnl_getapptrust(netdev, selectors, &nselectors); |
108 | + if (err) | 105 | + if (!err) { |
109 | + return -EMSGSIZE; | 106 | + for (i = 0; i < nselectors; i++) { |
110 | + | 107 | + err = nla_put_u8(skb, DCB_ATTR_DCB_APP_TRUST, |
111 | + for (i = 0; i < nselectors; i++) | 108 | + selectors[i]); |
112 | + nla_put_u8(skb, DCB_ATTR_DCB_APP_TRUST, selectors[i]); | 109 | + if (err) { |
110 | + nla_nest_cancel(skb, apptrust); | ||
111 | + return err; | ||
112 | + } | ||
113 | + } | ||
114 | + } | ||
113 | + | 115 | + |
114 | + nla_nest_end(skb, apptrust); | 116 | + nla_nest_end(skb, apptrust); |
115 | + } | 117 | + } |
116 | + | 118 | + |
117 | /* get peer info if available */ | 119 | /* get peer info if available */ |
118 | if (ops->ieee_peer_getets) { | 120 | if (ops->ieee_peer_getets) { |
119 | struct ieee_ets ets; | 121 | struct ieee_ets ets; |
120 | @@ -XXX,XX +XXX,XX @@ static int dcbnl_ieee_set(struct net_device *netdev, struct nlmsghdr *nlh, | 122 | @@ -XXX,XX +XXX,XX @@ static int dcbnl_ieee_set(struct net_device *netdev, struct nlmsghdr *nlh, |
121 | { | ||
122 | const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; | ||
123 | struct nlattr *ieee[DCB_ATTR_IEEE_MAX + 1]; | ||
124 | + int err, i; | ||
125 | int prio; | ||
126 | - int err; | ||
127 | |||
128 | if (!ops) | ||
129 | return -EOPNOTSUPP; | ||
130 | @@ -XXX,XX +XXX,XX @@ static int dcbnl_ieee_set(struct net_device *netdev, struct nlmsghdr *nlh, | ||
131 | } | 123 | } |
132 | } | 124 | } |
133 | 125 | ||
134 | + if (ieee[DCB_ATTR_DCB_APP_TRUST_TABLE]) { | 126 | + if (ieee[DCB_ATTR_DCB_APP_TRUST_TABLE]) { |
135 | + u8 selectors[IEEE_8021QAZ_APP_SEL_MAX + 1] = {0}; | 127 | + u8 selectors[IEEE_8021QAZ_APP_SEL_MAX + 1] = {0}; |
136 | + struct nlattr *attr; | 128 | + struct nlattr *attr; |
137 | + int nselectors = 0; | 129 | + int nselectors = 0; |
138 | + u8 selector; | 130 | + u8 selector; |
139 | + int rem; | 131 | + int rem, i; |
140 | + | 132 | + |
141 | + if (!ops->dcbnl_setapptrust) { | 133 | + if (!ops->dcbnl_setapptrust) { |
142 | + err = -EOPNOTSUPP; | 134 | + err = -EOPNOTSUPP; |
143 | + goto err; | 135 | + goto err; |
144 | + } | 136 | + } |
... | ... | diff view generated by jsdifflib |
1 | Add new registers and functions to support offload of pcp app entries. | 1 | Add new registers and functions to support offload of pcp app entries. |
---|---|---|---|
2 | 2 | ||
3 | Signed-off-by: Daniel Machon <daniel.machon@microchip.com> | 3 | Signed-off-by: Daniel Machon <daniel.machon@microchip.com> |
4 | --- | 4 | --- |
5 | drivers/net/ethernet/microchip/sparx5/Kconfig | 10 ++ | 5 | drivers/net/ethernet/microchip/sparx5/Kconfig | 10 ++ |
6 | .../net/ethernet/microchip/sparx5/Makefile | 2 + | 6 | .../net/ethernet/microchip/sparx5/Makefile | 2 + |
7 | .../ethernet/microchip/sparx5/sparx5_dcb.c | 116 ++++++++++++++++ | 7 | .../ethernet/microchip/sparx5/sparx5_dcb.c | 116 ++++++++++++++++ |
8 | .../ethernet/microchip/sparx5/sparx5_main.h | 11 ++ | 8 | .../ethernet/microchip/sparx5/sparx5_main.h | 11 ++ |
9 | .../microchip/sparx5/sparx5_main_regs.h | 127 +++++++++++++++++- | 9 | .../microchip/sparx5/sparx5_main_regs.h | 127 +++++++++++++++++- |
10 | .../ethernet/microchip/sparx5/sparx5_port.c | 37 +++++ | 10 | .../ethernet/microchip/sparx5/sparx5_port.c | 37 +++++ |
11 | .../ethernet/microchip/sparx5/sparx5_port.h | 17 +++ | 11 | .../ethernet/microchip/sparx5/sparx5_port.h | 17 +++ |
12 | .../ethernet/microchip/sparx5/sparx5_qos.c | 4 + | 12 | .../ethernet/microchip/sparx5/sparx5_qos.c | 4 + |
13 | 8 files changed, 322 insertions(+), 2 deletions(-) | 13 | 8 files changed, 322 insertions(+), 2 deletions(-) |
14 | create mode 100644 drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c | 14 | create mode 100644 drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c |
15 | 15 | ||
16 | diff --git a/drivers/net/ethernet/microchip/sparx5/Kconfig b/drivers/net/ethernet/microchip/sparx5/Kconfig | 16 | diff --git a/drivers/net/ethernet/microchip/sparx5/Kconfig b/drivers/net/ethernet/microchip/sparx5/Kconfig |
17 | index XXXXXXX..XXXXXXX 100644 | 17 | index XXXXXXX..XXXXXXX 100644 |
18 | --- a/drivers/net/ethernet/microchip/sparx5/Kconfig | 18 | --- a/drivers/net/ethernet/microchip/sparx5/Kconfig |
19 | +++ b/drivers/net/ethernet/microchip/sparx5/Kconfig | 19 | +++ b/drivers/net/ethernet/microchip/sparx5/Kconfig |
20 | @@ -XXX,XX +XXX,XX @@ config SPARX5_SWITCH | 20 | @@ -XXX,XX +XXX,XX @@ config SPARX5_SWITCH |
21 | select RESET_CONTROLLER | 21 | select RESET_CONTROLLER |
22 | help | 22 | help |
23 | This driver supports the Sparx5 network switch device. | 23 | This driver supports the Sparx5 network switch device. |
24 | + | 24 | + |
25 | +config SPARX5_DCB | 25 | +config SPARX5_DCB |
26 | + bool "Data Center Bridging (DCB) support" | 26 | + bool "Data Center Bridging (DCB) support" |
27 | + depends on SPARX5_SWITCH && DCB | 27 | + depends on SPARX5_SWITCH && DCB |
28 | + default y | 28 | + default y |
29 | + help | 29 | + help |
30 | + Say Y here if you want to use Data Center Bridging (DCB) in the | 30 | + Say Y here if you want to use Data Center Bridging (DCB) in the |
31 | + driver. | 31 | + driver. |
32 | + | 32 | + |
33 | + If unsure, set to Y. | 33 | + If unsure, set to Y. |
34 | diff --git a/drivers/net/ethernet/microchip/sparx5/Makefile b/drivers/net/ethernet/microchip/sparx5/Makefile | 34 | diff --git a/drivers/net/ethernet/microchip/sparx5/Makefile b/drivers/net/ethernet/microchip/sparx5/Makefile |
35 | index XXXXXXX..XXXXXXX 100644 | 35 | index XXXXXXX..XXXXXXX 100644 |
36 | --- a/drivers/net/ethernet/microchip/sparx5/Makefile | 36 | --- a/drivers/net/ethernet/microchip/sparx5/Makefile |
37 | +++ b/drivers/net/ethernet/microchip/sparx5/Makefile | 37 | +++ b/drivers/net/ethernet/microchip/sparx5/Makefile |
38 | @@ -XXX,XX +XXX,XX @@ sparx5-switch-objs := sparx5_main.o sparx5_packet.o \ | 38 | @@ -XXX,XX +XXX,XX @@ sparx5-switch-objs := sparx5_main.o sparx5_packet.o \ |
39 | sparx5_netdev.o sparx5_phylink.o sparx5_port.o sparx5_mactable.o sparx5_vlan.o \ | 39 | sparx5_netdev.o sparx5_phylink.o sparx5_port.o sparx5_mactable.o sparx5_vlan.o \ |
40 | sparx5_switchdev.o sparx5_calendar.o sparx5_ethtool.o sparx5_fdma.o \ | 40 | sparx5_switchdev.o sparx5_calendar.o sparx5_ethtool.o sparx5_fdma.o \ |
41 | sparx5_ptp.o sparx5_pgid.o sparx5_tc.o sparx5_qos.o | 41 | sparx5_ptp.o sparx5_pgid.o sparx5_tc.o sparx5_qos.o |
42 | + | 42 | + |
43 | + sparx5-switch-$(CONFIG_SPARX5_DCB) += sparx5_dcb.o | 43 | + sparx5-switch-$(CONFIG_SPARX5_DCB) += sparx5_dcb.o |
44 | \ No newline at end of file | 44 | \ No newline at end of file |
45 | diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c b/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c | 45 | diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c b/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c |
46 | new file mode 100644 | 46 | new file mode 100644 |
47 | index XXXXXXX..XXXXXXX | 47 | index XXXXXXX..XXXXXXX |
48 | --- /dev/null | 48 | --- /dev/null |
49 | +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c | 49 | +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c |
50 | @@ -XXX,XX +XXX,XX @@ | 50 | @@ -XXX,XX +XXX,XX @@ |
51 | +// SPDX-License-Identifier: GPL-2.0+ | 51 | +// SPDX-License-Identifier: GPL-2.0+ |
52 | +/* Microchip Sparx5 Switch driver | 52 | +/* Microchip Sparx5 Switch driver |
53 | + * | 53 | + * |
54 | + * Copyright (c) 2022 Microchip Technology Inc. and its subsidiaries. | 54 | + * Copyright (c) 2022 Microchip Technology Inc. and its subsidiaries. |
55 | + */ | 55 | + */ |
56 | + | 56 | + |
57 | +#include <net/dcbnl.h> | 57 | +#include <net/dcbnl.h> |
58 | + | 58 | + |
59 | +#include "sparx5_port.h" | 59 | +#include "sparx5_port.h" |
60 | + | 60 | + |
61 | +/* Validate app entry. | 61 | +/* Validate app entry. |
62 | + * | 62 | + * |
63 | + * Check for valid selectors and valid protocol and priority ranges. | 63 | + * Check for valid selectors and valid protocol and priority ranges. |
64 | + */ | 64 | + */ |
65 | +static int sparx5_dcb_app_validate(struct net_device *dev, | 65 | +static int sparx5_dcb_app_validate(struct net_device *dev, |
66 | + const struct dcb_app *app) | 66 | + const struct dcb_app *app) |
67 | +{ | 67 | +{ |
68 | + int err = 0; | 68 | + int err = 0; |
69 | + | 69 | + |
70 | + switch (app->selector) { | 70 | + switch (app->selector) { |
71 | + /* Pcp checks */ | 71 | + /* Pcp checks */ |
72 | + case DCB_APP_SEL_PCP: | 72 | + case DCB_APP_SEL_PCP: |
73 | + if (app->protocol > 15) | 73 | + if (app->protocol > 15) |
74 | + err = -EINVAL; | 74 | + err = -EINVAL; |
75 | + else if (app->priority >= SPX5_PRIOS) | 75 | + else if (app->priority >= SPX5_PRIOS) |
76 | + err = -ERANGE; | 76 | + err = -ERANGE; |
77 | + break; | 77 | + break; |
78 | + default: | 78 | + default: |
79 | + err = -EINVAL; | 79 | + err = -EINVAL; |
80 | + break; | 80 | + break; |
81 | + } | 81 | + } |
82 | + | 82 | + |
83 | + if (err) | 83 | + if (err) |
84 | + netdev_err(dev, "Invalid entry: %d:%d\n", app->protocol, | 84 | + netdev_err(dev, "Invalid entry: %d:%d\n", app->protocol, |
85 | + app->priority); | 85 | + app->priority); |
86 | + | 86 | + |
87 | + return err; | 87 | + return err; |
88 | +} | 88 | +} |
89 | + | 89 | + |
90 | +static int sparx5_dcb_app_update(struct net_device *dev) | 90 | +static int sparx5_dcb_app_update(struct net_device *dev) |
91 | +{ | 91 | +{ |
92 | + struct dcb_app app_itr = { .selector = DCB_APP_SEL_PCP }; | 92 | + struct dcb_app app_itr = { .selector = DCB_APP_SEL_PCP }; |
93 | + struct sparx5_port *port = netdev_priv(dev); | 93 | + struct sparx5_port *port = netdev_priv(dev); |
94 | + struct sparx5_port_qos_pcp_map *pcp_map; | 94 | + struct sparx5_port_qos_pcp_map *pcp_map; |
95 | + struct sparx5_port_qos qos = {0}; | 95 | + struct sparx5_port_qos qos = {0}; |
96 | + int i; | 96 | + int i; |
97 | + | 97 | + |
98 | + pcp_map = &qos.pcp.map; | 98 | + pcp_map = &qos.pcp.map; |
99 | + | 99 | + |
100 | + /* Get pcp ingress mapping */ | 100 | + /* Get pcp ingress mapping */ |
101 | + for (i = 0; i < ARRAY_SIZE(pcp_map->map); i++) { | 101 | + for (i = 0; i < ARRAY_SIZE(pcp_map->map); i++) { |
102 | + app_itr.protocol = i; | 102 | + app_itr.protocol = i; |
103 | + pcp_map->map[i] = dcb_getapp(dev, &app_itr); | 103 | + pcp_map->map[i] = dcb_getapp(dev, &app_itr); |
104 | + } | 104 | + } |
105 | + | 105 | + |
106 | + return sparx5_port_qos_set(port, &qos); | 106 | + return sparx5_port_qos_set(port, &qos); |
107 | +} | 107 | +} |
108 | + | 108 | + |
109 | +static int sparx5_dcb_ieee_setapp(struct net_device *dev, struct dcb_app *app) | 109 | +static int sparx5_dcb_ieee_setapp(struct net_device *dev, struct dcb_app *app) |
110 | +{ | 110 | +{ |
111 | + struct dcb_app app_itr; | 111 | + struct dcb_app app_itr; |
112 | + int err = 0; | 112 | + int err = 0; |
113 | + u8 prio; | 113 | + u8 prio; |
114 | + | 114 | + |
115 | + err = sparx5_dcb_app_validate(dev, app); | 115 | + err = sparx5_dcb_app_validate(dev, app); |
116 | + if (err) | 116 | + if (err) |
117 | + goto out; | 117 | + goto out; |
118 | + | 118 | + |
119 | + /* Delete current mapping, if it exists */ | 119 | + /* Delete current mapping, if it exists */ |
120 | + prio = dcb_getapp(dev, app); | 120 | + prio = dcb_getapp(dev, app); |
121 | + if (prio) { | 121 | + if (prio) { |
122 | + app_itr = *app; | 122 | + app_itr = *app; |
123 | + app_itr.priority = prio; | 123 | + app_itr.priority = prio; |
124 | + dcb_ieee_delapp(dev, &app_itr); | 124 | + dcb_ieee_delapp(dev, &app_itr); |
125 | + } | 125 | + } |
126 | + | 126 | + |
127 | + err = dcb_ieee_setapp(dev, app); | 127 | + err = dcb_ieee_setapp(dev, app); |
128 | + if (err) | 128 | + if (err) |
129 | + goto out; | 129 | + goto out; |
130 | + | 130 | + |
131 | + sparx5_dcb_app_update(dev); | 131 | + sparx5_dcb_app_update(dev); |
132 | + | 132 | + |
133 | +out: | 133 | +out: |
134 | + return err; | 134 | + return err; |
135 | +} | 135 | +} |
136 | + | 136 | + |
137 | +static int sparx5_dcb_ieee_delapp(struct net_device *dev, struct dcb_app *app) | 137 | +static int sparx5_dcb_ieee_delapp(struct net_device *dev, struct dcb_app *app) |
138 | +{ | 138 | +{ |
139 | + int err; | 139 | + int err; |
140 | + | 140 | + |
141 | + err = dcb_ieee_delapp(dev, app); | 141 | + err = dcb_ieee_delapp(dev, app); |
142 | + if (err < 0) | 142 | + if (err < 0) |
143 | + return err; | 143 | + return err; |
144 | + | 144 | + |
145 | + return sparx5_dcb_app_update(dev); | 145 | + return sparx5_dcb_app_update(dev); |
146 | +} | 146 | +} |
147 | + | 147 | + |
148 | +const struct dcbnl_rtnl_ops sparx5_dcbnl_ops = { | 148 | +const struct dcbnl_rtnl_ops sparx5_dcbnl_ops = { |
149 | + .ieee_setapp = sparx5_dcb_ieee_setapp, | 149 | + .ieee_setapp = sparx5_dcb_ieee_setapp, |
150 | + .ieee_delapp = sparx5_dcb_ieee_delapp, | 150 | + .ieee_delapp = sparx5_dcb_ieee_delapp, |
151 | +}; | 151 | +}; |
152 | + | 152 | + |
153 | +int sparx5_dcb_init(struct sparx5 *sparx5) | 153 | +int sparx5_dcb_init(struct sparx5 *sparx5) |
154 | +{ | 154 | +{ |
155 | + struct sparx5_port *port; | 155 | + struct sparx5_port *port; |
156 | + int i; | 156 | + int i; |
157 | + | 157 | + |
158 | + for (i = 0; i < SPX5_PORTS; i++) { | 158 | + for (i = 0; i < SPX5_PORTS; i++) { |
159 | + port = sparx5->ports[i]; | 159 | + port = sparx5->ports[i]; |
160 | + if (!port) | 160 | + if (!port) |
161 | + continue; | 161 | + continue; |
162 | + port->ndev->dcbnl_ops = &sparx5_dcbnl_ops; | 162 | + port->ndev->dcbnl_ops = &sparx5_dcbnl_ops; |
163 | + } | 163 | + } |
164 | + | 164 | + |
165 | + return 0; | 165 | + return 0; |
166 | +} | 166 | +} |
167 | diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h | 167 | diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h |
168 | index XXXXXXX..XXXXXXX 100644 | 168 | index XXXXXXX..XXXXXXX 100644 |
169 | --- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h | 169 | --- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h |
170 | +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h | 170 | +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h |
171 | @@ -XXX,XX +XXX,XX @@ int sparx5_config_dsm_calendar(struct sparx5 *sparx5); | 171 | @@ -XXX,XX +XXX,XX @@ int sparx5_config_dsm_calendar(struct sparx5 *sparx5); |
172 | void sparx5_get_stats64(struct net_device *ndev, struct rtnl_link_stats64 *stats); | 172 | void sparx5_get_stats64(struct net_device *ndev, struct rtnl_link_stats64 *stats); |
173 | int sparx_stats_init(struct sparx5 *sparx5); | 173 | int sparx_stats_init(struct sparx5 *sparx5); |
174 | 174 | ||
175 | +/* sparx5_dcb.c */ | 175 | +/* sparx5_dcb.c */ |
176 | +#ifdef CONFIG_SPARX5_DCB | 176 | +#ifdef CONFIG_SPARX5_DCB |
177 | +int sparx5_dcb_init(struct sparx5 *sparx5); | 177 | +int sparx5_dcb_init(struct sparx5 *sparx5); |
178 | +#else | 178 | +#else |
179 | +static inline int sparx5_dcb_init(struct sparx5 *sparx5) | 179 | +static inline int sparx5_dcb_init(struct sparx5 *sparx5) |
180 | +{ | 180 | +{ |
181 | + return 0; | 181 | + return 0; |
182 | +} | 182 | +} |
183 | +#endif | 183 | +#endif |
184 | + | 184 | + |
185 | /* sparx5_netdev.c */ | 185 | /* sparx5_netdev.c */ |
186 | void sparx5_set_port_ifh_timestamp(void *ifh_hdr, u64 timestamp); | 186 | void sparx5_set_port_ifh_timestamp(void *ifh_hdr, u64 timestamp); |
187 | void sparx5_set_port_ifh_rew_op(void *ifh_hdr, u32 rew_op); | 187 | void sparx5_set_port_ifh_rew_op(void *ifh_hdr, u32 rew_op); |
188 | @@ -XXX,XX +XXX,XX @@ static inline bool sparx5_is_baser(phy_interface_t interface) | 188 | @@ -XXX,XX +XXX,XX @@ static inline bool sparx5_is_baser(phy_interface_t interface) |
189 | extern const struct phylink_mac_ops sparx5_phylink_mac_ops; | 189 | extern const struct phylink_mac_ops sparx5_phylink_mac_ops; |
190 | extern const struct phylink_pcs_ops sparx5_phylink_pcs_ops; | 190 | extern const struct phylink_pcs_ops sparx5_phylink_pcs_ops; |
191 | extern const struct ethtool_ops sparx5_ethtool_ops; | 191 | extern const struct ethtool_ops sparx5_ethtool_ops; |
192 | +extern const struct dcbnl_rtnl_ops sparx5_dcbnl_ops; | 192 | +extern const struct dcbnl_rtnl_ops sparx5_dcbnl_ops; |
193 | 193 | ||
194 | /* Calculate raw offset */ | 194 | /* Calculate raw offset */ |
195 | static inline __pure int spx5_offset(int id, int tinst, int tcnt, | 195 | static inline __pure int spx5_offset(int id, int tinst, int tcnt, |
196 | diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main_regs.h b/drivers/net/ethernet/microchip/sparx5/sparx5_main_regs.h | 196 | diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main_regs.h b/drivers/net/ethernet/microchip/sparx5/sparx5_main_regs.h |
197 | index XXXXXXX..XXXXXXX 100644 | 197 | index XXXXXXX..XXXXXXX 100644 |
198 | --- a/drivers/net/ethernet/microchip/sparx5/sparx5_main_regs.h | 198 | --- a/drivers/net/ethernet/microchip/sparx5/sparx5_main_regs.h |
199 | +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main_regs.h | 199 | +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main_regs.h |
200 | @@ -XXX,XX +XXX,XX @@ | 200 | @@ -XXX,XX +XXX,XX @@ |
201 | * Copyright (c) 2021 Microchip Technology Inc. | 201 | * Copyright (c) 2021 Microchip Technology Inc. |
202 | */ | 202 | */ |
203 | 203 | ||
204 | -/* This file is autogenerated by cml-utils 2022-02-26 14:15:01 +0100. | 204 | -/* This file is autogenerated by cml-utils 2022-02-26 14:15:01 +0100. |
205 | - * Commit ID: 98bdd3d171cc2a1afd30d241d41a4281d471a48c (dirty) | 205 | - * Commit ID: 98bdd3d171cc2a1afd30d241d41a4281d471a48c (dirty) |
206 | +/* This file is autogenerated by cml-utils 2022-09-28 11:17:02 +0200. | 206 | +/* This file is autogenerated by cml-utils 2022-09-28 11:17:02 +0200. |
207 | + * Commit ID: 385c8a11d71a9f6a60368d3a3cb648fa257b479a | 207 | + * Commit ID: 385c8a11d71a9f6a60368d3a3cb648fa257b479a |
208 | */ | 208 | */ |
209 | 209 | ||
210 | #ifndef _SPARX5_MAIN_REGS_H_ | 210 | #ifndef _SPARX5_MAIN_REGS_H_ |
211 | @@ -XXX,XX +XXX,XX @@ enum sparx5_target { | 211 | @@ -XXX,XX +XXX,XX @@ enum sparx5_target { |
212 | #define ANA_CL_VLAN_CTRL_2_VLAN_PUSH_CNT_GET(x)\ | 212 | #define ANA_CL_VLAN_CTRL_2_VLAN_PUSH_CNT_GET(x)\ |
213 | FIELD_GET(ANA_CL_VLAN_CTRL_2_VLAN_PUSH_CNT, x) | 213 | FIELD_GET(ANA_CL_VLAN_CTRL_2_VLAN_PUSH_CNT, x) |
214 | 214 | ||
215 | +/* ANA_CL:PORT:PCP_DEI_MAP_CFG */ | 215 | +/* ANA_CL:PORT:PCP_DEI_MAP_CFG */ |
216 | +#define ANA_CL_PCP_DEI_MAP_CFG(g, r) __REG(TARGET_ANA_CL, 0, 1, 131072, g, 70, 512, 108, r, 16, 4) | 216 | +#define ANA_CL_PCP_DEI_MAP_CFG(g, r) __REG(TARGET_ANA_CL, 0, 1, 131072, g, 70, 512, 108, r, 16, 4) |
217 | + | 217 | + |
218 | +#define ANA_CL_PCP_DEI_MAP_CFG_PCP_DEI_DP_VAL GENMASK(4, 3) | 218 | +#define ANA_CL_PCP_DEI_MAP_CFG_PCP_DEI_DP_VAL GENMASK(4, 3) |
219 | +#define ANA_CL_PCP_DEI_MAP_CFG_PCP_DEI_DP_VAL_SET(x)\ | 219 | +#define ANA_CL_PCP_DEI_MAP_CFG_PCP_DEI_DP_VAL_SET(x)\ |
220 | + FIELD_PREP(ANA_CL_PCP_DEI_MAP_CFG_PCP_DEI_DP_VAL, x) | 220 | + FIELD_PREP(ANA_CL_PCP_DEI_MAP_CFG_PCP_DEI_DP_VAL, x) |
221 | +#define ANA_CL_PCP_DEI_MAP_CFG_PCP_DEI_DP_VAL_GET(x)\ | 221 | +#define ANA_CL_PCP_DEI_MAP_CFG_PCP_DEI_DP_VAL_GET(x)\ |
222 | + FIELD_GET(ANA_CL_PCP_DEI_MAP_CFG_PCP_DEI_DP_VAL, x) | 222 | + FIELD_GET(ANA_CL_PCP_DEI_MAP_CFG_PCP_DEI_DP_VAL, x) |
223 | + | 223 | + |
224 | +#define ANA_CL_PCP_DEI_MAP_CFG_PCP_DEI_QOS_VAL GENMASK(2, 0) | 224 | +#define ANA_CL_PCP_DEI_MAP_CFG_PCP_DEI_QOS_VAL GENMASK(2, 0) |
225 | +#define ANA_CL_PCP_DEI_MAP_CFG_PCP_DEI_QOS_VAL_SET(x)\ | 225 | +#define ANA_CL_PCP_DEI_MAP_CFG_PCP_DEI_QOS_VAL_SET(x)\ |
226 | + FIELD_PREP(ANA_CL_PCP_DEI_MAP_CFG_PCP_DEI_QOS_VAL, x) | 226 | + FIELD_PREP(ANA_CL_PCP_DEI_MAP_CFG_PCP_DEI_QOS_VAL, x) |
227 | +#define ANA_CL_PCP_DEI_MAP_CFG_PCP_DEI_QOS_VAL_GET(x)\ | 227 | +#define ANA_CL_PCP_DEI_MAP_CFG_PCP_DEI_QOS_VAL_GET(x)\ |
228 | + FIELD_GET(ANA_CL_PCP_DEI_MAP_CFG_PCP_DEI_QOS_VAL, x) | 228 | + FIELD_GET(ANA_CL_PCP_DEI_MAP_CFG_PCP_DEI_QOS_VAL, x) |
229 | + | 229 | + |
230 | +/* ANA_CL:PORT:QOS_CFG */ | 230 | +/* ANA_CL:PORT:QOS_CFG */ |
231 | +#define ANA_CL_QOS_CFG(g) __REG(TARGET_ANA_CL, 0, 1, 131072, g, 70, 512, 172, 0, 1, 4) | 231 | +#define ANA_CL_QOS_CFG(g) __REG(TARGET_ANA_CL, 0, 1, 131072, g, 70, 512, 172, 0, 1, 4) |
232 | + | 232 | + |
233 | +#define ANA_CL_QOS_CFG_DEFAULT_COSID_ENA BIT(17) | 233 | +#define ANA_CL_QOS_CFG_DEFAULT_COSID_ENA BIT(17) |
234 | +#define ANA_CL_QOS_CFG_DEFAULT_COSID_ENA_SET(x)\ | 234 | +#define ANA_CL_QOS_CFG_DEFAULT_COSID_ENA_SET(x)\ |
235 | + FIELD_PREP(ANA_CL_QOS_CFG_DEFAULT_COSID_ENA, x) | 235 | + FIELD_PREP(ANA_CL_QOS_CFG_DEFAULT_COSID_ENA, x) |
236 | +#define ANA_CL_QOS_CFG_DEFAULT_COSID_ENA_GET(x)\ | 236 | +#define ANA_CL_QOS_CFG_DEFAULT_COSID_ENA_GET(x)\ |
237 | + FIELD_GET(ANA_CL_QOS_CFG_DEFAULT_COSID_ENA, x) | 237 | + FIELD_GET(ANA_CL_QOS_CFG_DEFAULT_COSID_ENA, x) |
238 | + | 238 | + |
239 | +#define ANA_CL_QOS_CFG_DEFAULT_COSID_VAL GENMASK(16, 14) | 239 | +#define ANA_CL_QOS_CFG_DEFAULT_COSID_VAL GENMASK(16, 14) |
240 | +#define ANA_CL_QOS_CFG_DEFAULT_COSID_VAL_SET(x)\ | 240 | +#define ANA_CL_QOS_CFG_DEFAULT_COSID_VAL_SET(x)\ |
241 | + FIELD_PREP(ANA_CL_QOS_CFG_DEFAULT_COSID_VAL, x) | 241 | + FIELD_PREP(ANA_CL_QOS_CFG_DEFAULT_COSID_VAL, x) |
242 | +#define ANA_CL_QOS_CFG_DEFAULT_COSID_VAL_GET(x)\ | 242 | +#define ANA_CL_QOS_CFG_DEFAULT_COSID_VAL_GET(x)\ |
243 | + FIELD_GET(ANA_CL_QOS_CFG_DEFAULT_COSID_VAL, x) | 243 | + FIELD_GET(ANA_CL_QOS_CFG_DEFAULT_COSID_VAL, x) |
244 | + | 244 | + |
245 | +#define ANA_CL_QOS_CFG_DSCP_REWR_MODE_SEL GENMASK(13, 12) | 245 | +#define ANA_CL_QOS_CFG_DSCP_REWR_MODE_SEL GENMASK(13, 12) |
246 | +#define ANA_CL_QOS_CFG_DSCP_REWR_MODE_SEL_SET(x)\ | 246 | +#define ANA_CL_QOS_CFG_DSCP_REWR_MODE_SEL_SET(x)\ |
247 | + FIELD_PREP(ANA_CL_QOS_CFG_DSCP_REWR_MODE_SEL, x) | 247 | + FIELD_PREP(ANA_CL_QOS_CFG_DSCP_REWR_MODE_SEL, x) |
248 | +#define ANA_CL_QOS_CFG_DSCP_REWR_MODE_SEL_GET(x)\ | 248 | +#define ANA_CL_QOS_CFG_DSCP_REWR_MODE_SEL_GET(x)\ |
249 | + FIELD_GET(ANA_CL_QOS_CFG_DSCP_REWR_MODE_SEL, x) | 249 | + FIELD_GET(ANA_CL_QOS_CFG_DSCP_REWR_MODE_SEL, x) |
250 | + | 250 | + |
251 | +#define ANA_CL_QOS_CFG_DSCP_TRANSLATE_ENA BIT(11) | 251 | +#define ANA_CL_QOS_CFG_DSCP_TRANSLATE_ENA BIT(11) |
252 | +#define ANA_CL_QOS_CFG_DSCP_TRANSLATE_ENA_SET(x)\ | 252 | +#define ANA_CL_QOS_CFG_DSCP_TRANSLATE_ENA_SET(x)\ |
253 | + FIELD_PREP(ANA_CL_QOS_CFG_DSCP_TRANSLATE_ENA, x) | 253 | + FIELD_PREP(ANA_CL_QOS_CFG_DSCP_TRANSLATE_ENA, x) |
254 | +#define ANA_CL_QOS_CFG_DSCP_TRANSLATE_ENA_GET(x)\ | 254 | +#define ANA_CL_QOS_CFG_DSCP_TRANSLATE_ENA_GET(x)\ |
255 | + FIELD_GET(ANA_CL_QOS_CFG_DSCP_TRANSLATE_ENA, x) | 255 | + FIELD_GET(ANA_CL_QOS_CFG_DSCP_TRANSLATE_ENA, x) |
256 | + | 256 | + |
257 | +#define ANA_CL_QOS_CFG_DSCP_KEEP_ENA BIT(10) | 257 | +#define ANA_CL_QOS_CFG_DSCP_KEEP_ENA BIT(10) |
258 | +#define ANA_CL_QOS_CFG_DSCP_KEEP_ENA_SET(x)\ | 258 | +#define ANA_CL_QOS_CFG_DSCP_KEEP_ENA_SET(x)\ |
259 | + FIELD_PREP(ANA_CL_QOS_CFG_DSCP_KEEP_ENA, x) | 259 | + FIELD_PREP(ANA_CL_QOS_CFG_DSCP_KEEP_ENA, x) |
260 | +#define ANA_CL_QOS_CFG_DSCP_KEEP_ENA_GET(x)\ | 260 | +#define ANA_CL_QOS_CFG_DSCP_KEEP_ENA_GET(x)\ |
261 | + FIELD_GET(ANA_CL_QOS_CFG_DSCP_KEEP_ENA, x) | 261 | + FIELD_GET(ANA_CL_QOS_CFG_DSCP_KEEP_ENA, x) |
262 | + | 262 | + |
263 | +#define ANA_CL_QOS_CFG_KEEP_ENA BIT(9) | 263 | +#define ANA_CL_QOS_CFG_KEEP_ENA BIT(9) |
264 | +#define ANA_CL_QOS_CFG_KEEP_ENA_SET(x)\ | 264 | +#define ANA_CL_QOS_CFG_KEEP_ENA_SET(x)\ |
265 | + FIELD_PREP(ANA_CL_QOS_CFG_KEEP_ENA, x) | 265 | + FIELD_PREP(ANA_CL_QOS_CFG_KEEP_ENA, x) |
266 | +#define ANA_CL_QOS_CFG_KEEP_ENA_GET(x)\ | 266 | +#define ANA_CL_QOS_CFG_KEEP_ENA_GET(x)\ |
267 | + FIELD_GET(ANA_CL_QOS_CFG_KEEP_ENA, x) | 267 | + FIELD_GET(ANA_CL_QOS_CFG_KEEP_ENA, x) |
268 | + | 268 | + |
269 | +#define ANA_CL_QOS_CFG_PCP_DEI_DP_ENA BIT(8) | 269 | +#define ANA_CL_QOS_CFG_PCP_DEI_DP_ENA BIT(8) |
270 | +#define ANA_CL_QOS_CFG_PCP_DEI_DP_ENA_SET(x)\ | 270 | +#define ANA_CL_QOS_CFG_PCP_DEI_DP_ENA_SET(x)\ |
271 | + FIELD_PREP(ANA_CL_QOS_CFG_PCP_DEI_DP_ENA, x) | 271 | + FIELD_PREP(ANA_CL_QOS_CFG_PCP_DEI_DP_ENA, x) |
272 | +#define ANA_CL_QOS_CFG_PCP_DEI_DP_ENA_GET(x)\ | 272 | +#define ANA_CL_QOS_CFG_PCP_DEI_DP_ENA_GET(x)\ |
273 | + FIELD_GET(ANA_CL_QOS_CFG_PCP_DEI_DP_ENA, x) | 273 | + FIELD_GET(ANA_CL_QOS_CFG_PCP_DEI_DP_ENA, x) |
274 | + | 274 | + |
275 | +#define ANA_CL_QOS_CFG_PCP_DEI_QOS_ENA BIT(7) | 275 | +#define ANA_CL_QOS_CFG_PCP_DEI_QOS_ENA BIT(7) |
276 | +#define ANA_CL_QOS_CFG_PCP_DEI_QOS_ENA_SET(x)\ | 276 | +#define ANA_CL_QOS_CFG_PCP_DEI_QOS_ENA_SET(x)\ |
277 | + FIELD_PREP(ANA_CL_QOS_CFG_PCP_DEI_QOS_ENA, x) | 277 | + FIELD_PREP(ANA_CL_QOS_CFG_PCP_DEI_QOS_ENA, x) |
278 | +#define ANA_CL_QOS_CFG_PCP_DEI_QOS_ENA_GET(x)\ | 278 | +#define ANA_CL_QOS_CFG_PCP_DEI_QOS_ENA_GET(x)\ |
279 | + FIELD_GET(ANA_CL_QOS_CFG_PCP_DEI_QOS_ENA, x) | 279 | + FIELD_GET(ANA_CL_QOS_CFG_PCP_DEI_QOS_ENA, x) |
280 | + | 280 | + |
281 | +#define ANA_CL_QOS_CFG_DSCP_DP_ENA BIT(6) | 281 | +#define ANA_CL_QOS_CFG_DSCP_DP_ENA BIT(6) |
282 | +#define ANA_CL_QOS_CFG_DSCP_DP_ENA_SET(x)\ | 282 | +#define ANA_CL_QOS_CFG_DSCP_DP_ENA_SET(x)\ |
283 | + FIELD_PREP(ANA_CL_QOS_CFG_DSCP_DP_ENA, x) | 283 | + FIELD_PREP(ANA_CL_QOS_CFG_DSCP_DP_ENA, x) |
284 | +#define ANA_CL_QOS_CFG_DSCP_DP_ENA_GET(x)\ | 284 | +#define ANA_CL_QOS_CFG_DSCP_DP_ENA_GET(x)\ |
285 | + FIELD_GET(ANA_CL_QOS_CFG_DSCP_DP_ENA, x) | 285 | + FIELD_GET(ANA_CL_QOS_CFG_DSCP_DP_ENA, x) |
286 | + | 286 | + |
287 | +#define ANA_CL_QOS_CFG_DSCP_QOS_ENA BIT(5) | 287 | +#define ANA_CL_QOS_CFG_DSCP_QOS_ENA BIT(5) |
288 | +#define ANA_CL_QOS_CFG_DSCP_QOS_ENA_SET(x)\ | 288 | +#define ANA_CL_QOS_CFG_DSCP_QOS_ENA_SET(x)\ |
289 | + FIELD_PREP(ANA_CL_QOS_CFG_DSCP_QOS_ENA, x) | 289 | + FIELD_PREP(ANA_CL_QOS_CFG_DSCP_QOS_ENA, x) |
290 | +#define ANA_CL_QOS_CFG_DSCP_QOS_ENA_GET(x)\ | 290 | +#define ANA_CL_QOS_CFG_DSCP_QOS_ENA_GET(x)\ |
291 | + FIELD_GET(ANA_CL_QOS_CFG_DSCP_QOS_ENA, x) | 291 | + FIELD_GET(ANA_CL_QOS_CFG_DSCP_QOS_ENA, x) |
292 | + | 292 | + |
293 | +#define ANA_CL_QOS_CFG_DEFAULT_DP_VAL GENMASK(4, 3) | 293 | +#define ANA_CL_QOS_CFG_DEFAULT_DP_VAL GENMASK(4, 3) |
294 | +#define ANA_CL_QOS_CFG_DEFAULT_DP_VAL_SET(x)\ | 294 | +#define ANA_CL_QOS_CFG_DEFAULT_DP_VAL_SET(x)\ |
295 | + FIELD_PREP(ANA_CL_QOS_CFG_DEFAULT_DP_VAL, x) | 295 | + FIELD_PREP(ANA_CL_QOS_CFG_DEFAULT_DP_VAL, x) |
296 | +#define ANA_CL_QOS_CFG_DEFAULT_DP_VAL_GET(x)\ | 296 | +#define ANA_CL_QOS_CFG_DEFAULT_DP_VAL_GET(x)\ |
297 | + FIELD_GET(ANA_CL_QOS_CFG_DEFAULT_DP_VAL, x) | 297 | + FIELD_GET(ANA_CL_QOS_CFG_DEFAULT_DP_VAL, x) |
298 | + | 298 | + |
299 | +#define ANA_CL_QOS_CFG_DEFAULT_QOS_VAL GENMASK(2, 0) | 299 | +#define ANA_CL_QOS_CFG_DEFAULT_QOS_VAL GENMASK(2, 0) |
300 | +#define ANA_CL_QOS_CFG_DEFAULT_QOS_VAL_SET(x)\ | 300 | +#define ANA_CL_QOS_CFG_DEFAULT_QOS_VAL_SET(x)\ |
301 | + FIELD_PREP(ANA_CL_QOS_CFG_DEFAULT_QOS_VAL, x) | 301 | + FIELD_PREP(ANA_CL_QOS_CFG_DEFAULT_QOS_VAL, x) |
302 | +#define ANA_CL_QOS_CFG_DEFAULT_QOS_VAL_GET(x)\ | 302 | +#define ANA_CL_QOS_CFG_DEFAULT_QOS_VAL_GET(x)\ |
303 | + FIELD_GET(ANA_CL_QOS_CFG_DEFAULT_QOS_VAL, x) | 303 | + FIELD_GET(ANA_CL_QOS_CFG_DEFAULT_QOS_VAL, x) |
304 | + | 304 | + |
305 | /* ANA_CL:PORT:CAPTURE_BPDU_CFG */ | 305 | /* ANA_CL:PORT:CAPTURE_BPDU_CFG */ |
306 | #define ANA_CL_CAPTURE_BPDU_CFG(g) __REG(TARGET_ANA_CL, 0, 1, 131072, g, 70, 512, 196, 0, 1, 4) | 306 | #define ANA_CL_CAPTURE_BPDU_CFG(g) __REG(TARGET_ANA_CL, 0, 1, 131072, g, 70, 512, 196, 0, 1, 4) |
307 | 307 | ||
308 | @@ -XXX,XX +XXX,XX @@ enum sparx5_target { | 308 | @@ -XXX,XX +XXX,XX @@ enum sparx5_target { |
309 | #define ANA_CL_OWN_UPSID_OWN_UPSID_GET(x)\ | 309 | #define ANA_CL_OWN_UPSID_OWN_UPSID_GET(x)\ |
310 | FIELD_GET(ANA_CL_OWN_UPSID_OWN_UPSID, x) | 310 | FIELD_GET(ANA_CL_OWN_UPSID_OWN_UPSID, x) |
311 | 311 | ||
312 | +/* ANA_CL:COMMON:DSCP_CFG */ | 312 | +/* ANA_CL:COMMON:DSCP_CFG */ |
313 | +#define ANA_CL_DSCP_CFG(r) __REG(TARGET_ANA_CL, 0, 1, 166912, 0, 1, 756, 256, r, 64, 4) | 313 | +#define ANA_CL_DSCP_CFG(r) __REG(TARGET_ANA_CL, 0, 1, 166912, 0, 1, 756, 256, r, 64, 4) |
314 | + | 314 | + |
315 | +#define ANA_CL_DSCP_CFG_DSCP_TRANSLATE_VAL GENMASK(12, 7) | 315 | +#define ANA_CL_DSCP_CFG_DSCP_TRANSLATE_VAL GENMASK(12, 7) |
316 | +#define ANA_CL_DSCP_CFG_DSCP_TRANSLATE_VAL_SET(x)\ | 316 | +#define ANA_CL_DSCP_CFG_DSCP_TRANSLATE_VAL_SET(x)\ |
317 | + FIELD_PREP(ANA_CL_DSCP_CFG_DSCP_TRANSLATE_VAL, x) | 317 | + FIELD_PREP(ANA_CL_DSCP_CFG_DSCP_TRANSLATE_VAL, x) |
318 | +#define ANA_CL_DSCP_CFG_DSCP_TRANSLATE_VAL_GET(x)\ | 318 | +#define ANA_CL_DSCP_CFG_DSCP_TRANSLATE_VAL_GET(x)\ |
319 | + FIELD_GET(ANA_CL_DSCP_CFG_DSCP_TRANSLATE_VAL, x) | 319 | + FIELD_GET(ANA_CL_DSCP_CFG_DSCP_TRANSLATE_VAL, x) |
320 | + | 320 | + |
321 | +#define ANA_CL_DSCP_CFG_DSCP_QOS_VAL GENMASK(6, 4) | 321 | +#define ANA_CL_DSCP_CFG_DSCP_QOS_VAL GENMASK(6, 4) |
322 | +#define ANA_CL_DSCP_CFG_DSCP_QOS_VAL_SET(x)\ | 322 | +#define ANA_CL_DSCP_CFG_DSCP_QOS_VAL_SET(x)\ |
323 | + FIELD_PREP(ANA_CL_DSCP_CFG_DSCP_QOS_VAL, x) | 323 | + FIELD_PREP(ANA_CL_DSCP_CFG_DSCP_QOS_VAL, x) |
324 | +#define ANA_CL_DSCP_CFG_DSCP_QOS_VAL_GET(x)\ | 324 | +#define ANA_CL_DSCP_CFG_DSCP_QOS_VAL_GET(x)\ |
325 | + FIELD_GET(ANA_CL_DSCP_CFG_DSCP_QOS_VAL, x) | 325 | + FIELD_GET(ANA_CL_DSCP_CFG_DSCP_QOS_VAL, x) |
326 | + | 326 | + |
327 | +#define ANA_CL_DSCP_CFG_DSCP_DP_VAL GENMASK(3, 2) | 327 | +#define ANA_CL_DSCP_CFG_DSCP_DP_VAL GENMASK(3, 2) |
328 | +#define ANA_CL_DSCP_CFG_DSCP_DP_VAL_SET(x)\ | 328 | +#define ANA_CL_DSCP_CFG_DSCP_DP_VAL_SET(x)\ |
329 | + FIELD_PREP(ANA_CL_DSCP_CFG_DSCP_DP_VAL, x) | 329 | + FIELD_PREP(ANA_CL_DSCP_CFG_DSCP_DP_VAL, x) |
330 | +#define ANA_CL_DSCP_CFG_DSCP_DP_VAL_GET(x)\ | 330 | +#define ANA_CL_DSCP_CFG_DSCP_DP_VAL_GET(x)\ |
331 | + FIELD_GET(ANA_CL_DSCP_CFG_DSCP_DP_VAL, x) | 331 | + FIELD_GET(ANA_CL_DSCP_CFG_DSCP_DP_VAL, x) |
332 | + | 332 | + |
333 | +#define ANA_CL_DSCP_CFG_DSCP_REWR_ENA BIT(1) | 333 | +#define ANA_CL_DSCP_CFG_DSCP_REWR_ENA BIT(1) |
334 | +#define ANA_CL_DSCP_CFG_DSCP_REWR_ENA_SET(x)\ | 334 | +#define ANA_CL_DSCP_CFG_DSCP_REWR_ENA_SET(x)\ |
335 | + FIELD_PREP(ANA_CL_DSCP_CFG_DSCP_REWR_ENA, x) | 335 | + FIELD_PREP(ANA_CL_DSCP_CFG_DSCP_REWR_ENA, x) |
336 | +#define ANA_CL_DSCP_CFG_DSCP_REWR_ENA_GET(x)\ | 336 | +#define ANA_CL_DSCP_CFG_DSCP_REWR_ENA_GET(x)\ |
337 | + FIELD_GET(ANA_CL_DSCP_CFG_DSCP_REWR_ENA, x) | 337 | + FIELD_GET(ANA_CL_DSCP_CFG_DSCP_REWR_ENA, x) |
338 | + | 338 | + |
339 | +#define ANA_CL_DSCP_CFG_DSCP_TRUST_ENA BIT(0) | 339 | +#define ANA_CL_DSCP_CFG_DSCP_TRUST_ENA BIT(0) |
340 | +#define ANA_CL_DSCP_CFG_DSCP_TRUST_ENA_SET(x)\ | 340 | +#define ANA_CL_DSCP_CFG_DSCP_TRUST_ENA_SET(x)\ |
341 | + FIELD_PREP(ANA_CL_DSCP_CFG_DSCP_TRUST_ENA, x) | 341 | + FIELD_PREP(ANA_CL_DSCP_CFG_DSCP_TRUST_ENA, x) |
342 | +#define ANA_CL_DSCP_CFG_DSCP_TRUST_ENA_GET(x)\ | 342 | +#define ANA_CL_DSCP_CFG_DSCP_TRUST_ENA_GET(x)\ |
343 | + FIELD_GET(ANA_CL_DSCP_CFG_DSCP_TRUST_ENA, x) | 343 | + FIELD_GET(ANA_CL_DSCP_CFG_DSCP_TRUST_ENA, x) |
344 | + | 344 | + |
345 | /* ANA_L2:COMMON:AUTO_LRN_CFG */ | 345 | /* ANA_L2:COMMON:AUTO_LRN_CFG */ |
346 | #define ANA_L2_AUTO_LRN_CFG __REG(TARGET_ANA_L2, 0, 1, 566024, 0, 1, 700, 24, 0, 1, 4) | 346 | #define ANA_L2_AUTO_LRN_CFG __REG(TARGET_ANA_L2, 0, 1, 566024, 0, 1, 700, 24, 0, 1, 4) |
347 | 347 | ||
348 | diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c | 348 | diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c |
349 | index XXXXXXX..XXXXXXX 100644 | 349 | index XXXXXXX..XXXXXXX 100644 |
350 | --- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c | 350 | --- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c |
351 | +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c | 351 | +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c |
352 | @@ -XXX,XX +XXX,XX @@ | 352 | @@ -XXX,XX +XXX,XX @@ |
353 | 353 | ||
354 | #include <linux/module.h> | 354 | #include <linux/module.h> |
355 | #include <linux/phy/phy.h> | 355 | #include <linux/phy/phy.h> |
356 | +#include <net/dcbnl.h> | 356 | +#include <net/dcbnl.h> |
357 | 357 | ||
358 | #include "sparx5_main_regs.h" | 358 | #include "sparx5_main_regs.h" |
359 | #include "sparx5_main.h" | 359 | #include "sparx5_main.h" |
360 | @@ -XXX,XX +XXX,XX @@ void sparx5_port_enable(struct sparx5_port *port, bool enable) | 360 | @@ -XXX,XX +XXX,XX @@ void sparx5_port_enable(struct sparx5_port *port, bool enable) |
361 | sparx5, | 361 | sparx5, |
362 | QFWD_SWITCH_PORT_MODE(port->portno)); | 362 | QFWD_SWITCH_PORT_MODE(port->portno)); |
363 | } | 363 | } |
364 | + | 364 | + |
365 | +int sparx5_port_qos_set(struct sparx5_port *port, | 365 | +int sparx5_port_qos_set(struct sparx5_port *port, |
366 | + struct sparx5_port_qos *qos) | 366 | + struct sparx5_port_qos *qos) |
367 | +{ | 367 | +{ |
368 | + sparx5_port_qos_pcp_set(port, &qos->pcp); | 368 | + sparx5_port_qos_pcp_set(port, &qos->pcp); |
369 | + | 369 | + |
370 | + return 0; | 370 | + return 0; |
371 | +} | 371 | +} |
372 | + | 372 | + |
373 | +int sparx5_port_qos_pcp_set(const struct sparx5_port *port, | 373 | +int sparx5_port_qos_pcp_set(const struct sparx5_port *port, |
374 | + struct sparx5_port_qos_pcp *qos) | 374 | + struct sparx5_port_qos_pcp *qos) |
375 | +{ | 375 | +{ |
376 | + struct sparx5 *sparx5 = port->sparx5; | 376 | + struct sparx5 *sparx5 = port->sparx5; |
377 | + u8 *pcp_itr = qos->map.map; | 377 | + u8 *pcp_itr = qos->map.map; |
378 | + u8 pcp, dp; | 378 | + u8 pcp, dp; |
379 | + int i; | 379 | + int i; |
380 | + | 380 | + |
381 | + /* Enable/disable pcp and dp for qos classification. */ | 381 | + /* Enable/disable pcp and dp for qos classification. */ |
382 | + spx5_rmw(ANA_CL_QOS_CFG_PCP_DEI_QOS_ENA_SET(1) | | 382 | + spx5_rmw(ANA_CL_QOS_CFG_PCP_DEI_QOS_ENA_SET(1) | |
383 | + ANA_CL_QOS_CFG_PCP_DEI_DP_ENA_SET(1), | 383 | + ANA_CL_QOS_CFG_PCP_DEI_DP_ENA_SET(1), |
384 | + ANA_CL_QOS_CFG_PCP_DEI_QOS_ENA | ANA_CL_QOS_CFG_PCP_DEI_DP_ENA, | 384 | + ANA_CL_QOS_CFG_PCP_DEI_QOS_ENA | ANA_CL_QOS_CFG_PCP_DEI_DP_ENA, |
385 | + sparx5, ANA_CL_QOS_CFG(port->portno)); | 385 | + sparx5, ANA_CL_QOS_CFG(port->portno)); |
386 | + | 386 | + |
387 | + /* Map each pcp and dei value to priority and dp */ | 387 | + /* Map each pcp and dei value to priority and dp */ |
388 | + for (i = 0; i < ARRAY_SIZE(qos->map.map); i++) { | 388 | + for (i = 0; i < ARRAY_SIZE(qos->map.map); i++) { |
389 | + pcp = *(pcp_itr + i); | 389 | + pcp = *(pcp_itr + i); |
390 | + dp = (i <= 7) ? 0 : 1; | 390 | + dp = (i <= 7) ? 0 : 1; |
391 | + spx5_rmw(ANA_CL_PCP_DEI_MAP_CFG_PCP_DEI_QOS_VAL_SET(pcp) | | 391 | + spx5_rmw(ANA_CL_PCP_DEI_MAP_CFG_PCP_DEI_QOS_VAL_SET(pcp) | |
392 | + ANA_CL_PCP_DEI_MAP_CFG_PCP_DEI_DP_VAL_SET(dp), | 392 | + ANA_CL_PCP_DEI_MAP_CFG_PCP_DEI_DP_VAL_SET(dp), |
393 | + ANA_CL_PCP_DEI_MAP_CFG_PCP_DEI_QOS_VAL | | 393 | + ANA_CL_PCP_DEI_MAP_CFG_PCP_DEI_QOS_VAL | |
394 | + ANA_CL_PCP_DEI_MAP_CFG_PCP_DEI_DP_VAL, sparx5, | 394 | + ANA_CL_PCP_DEI_MAP_CFG_PCP_DEI_DP_VAL, sparx5, |
395 | + ANA_CL_PCP_DEI_MAP_CFG(port->portno, i)); | 395 | + ANA_CL_PCP_DEI_MAP_CFG(port->portno, i)); |
396 | + } | 396 | + } |
397 | + | 397 | + |
398 | + return 0; | 398 | + return 0; |
399 | +} | 399 | +} |
400 | diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.h b/drivers/net/ethernet/microchip/sparx5/sparx5_port.h | 400 | diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.h b/drivers/net/ethernet/microchip/sparx5/sparx5_port.h |
401 | index XXXXXXX..XXXXXXX 100644 | 401 | index XXXXXXX..XXXXXXX 100644 |
402 | --- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.h | 402 | --- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.h |
403 | +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.h | 403 | +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.h |
404 | @@ -XXX,XX +XXX,XX @@ int sparx5_get_port_status(struct sparx5 *sparx5, | 404 | @@ -XXX,XX +XXX,XX @@ int sparx5_get_port_status(struct sparx5 *sparx5, |
405 | void sparx5_port_enable(struct sparx5_port *port, bool enable); | 405 | void sparx5_port_enable(struct sparx5_port *port, bool enable); |
406 | int sparx5_port_fwd_urg(struct sparx5 *sparx5, u32 speed); | 406 | int sparx5_port_fwd_urg(struct sparx5 *sparx5, u32 speed); |
407 | 407 | ||
408 | +struct sparx5_port_qos_pcp_map { | 408 | +struct sparx5_port_qos_pcp_map { |
409 | + u8 map[16]; | 409 | + u8 map[16]; |
410 | +}; | 410 | +}; |
411 | + | 411 | + |
412 | +struct sparx5_port_qos_pcp { | 412 | +struct sparx5_port_qos_pcp { |
413 | + struct sparx5_port_qos_pcp_map map; | 413 | + struct sparx5_port_qos_pcp_map map; |
414 | +}; | 414 | +}; |
415 | + | 415 | + |
416 | +struct sparx5_port_qos { | 416 | +struct sparx5_port_qos { |
417 | + struct sparx5_port_qos_pcp pcp; | 417 | + struct sparx5_port_qos_pcp pcp; |
418 | +}; | 418 | +}; |
419 | + | 419 | + |
420 | +int sparx5_port_qos_set(struct sparx5_port *port, struct sparx5_port_qos *qos); | 420 | +int sparx5_port_qos_set(struct sparx5_port *port, struct sparx5_port_qos *qos); |
421 | + | 421 | + |
422 | +int sparx5_port_qos_pcp_set(const struct sparx5_port *port, | 422 | +int sparx5_port_qos_pcp_set(const struct sparx5_port *port, |
423 | + struct sparx5_port_qos_pcp *qos); | 423 | + struct sparx5_port_qos_pcp *qos); |
424 | + | 424 | + |
425 | #endif /* __SPARX5_PORT_H__ */ | 425 | #endif /* __SPARX5_PORT_H__ */ |
426 | diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_qos.c b/drivers/net/ethernet/microchip/sparx5/sparx5_qos.c | 426 | diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_qos.c b/drivers/net/ethernet/microchip/sparx5/sparx5_qos.c |
427 | index XXXXXXX..XXXXXXX 100644 | 427 | index XXXXXXX..XXXXXXX 100644 |
428 | --- a/drivers/net/ethernet/microchip/sparx5/sparx5_qos.c | 428 | --- a/drivers/net/ethernet/microchip/sparx5/sparx5_qos.c |
429 | +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_qos.c | 429 | +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_qos.c |
430 | @@ -XXX,XX +XXX,XX @@ int sparx5_qos_init(struct sparx5 *sparx5) | 430 | @@ -XXX,XX +XXX,XX @@ int sparx5_qos_init(struct sparx5 *sparx5) |
431 | if (ret < 0) | 431 | if (ret < 0) |
432 | return ret; | 432 | return ret; |
433 | 433 | ||
434 | + ret = sparx5_dcb_init(sparx5); | 434 | + ret = sparx5_dcb_init(sparx5); |
435 | + if (ret < 0) | 435 | + if (ret < 0) |
436 | + return ret; | 436 | + return ret; |
437 | + | 437 | + |
438 | return 0; | 438 | return 0; |
439 | } | 439 | } |
440 | 440 | ||
441 | -- | 441 | -- |
442 | 2.34.1 | 442 | 2.34.1 | diff view generated by jsdifflib |
1 | Make use of set/getapptrust() to implement per-selector trust and trust | 1 | Make use of set/getapptrust() to implement per-selector trust and trust |
---|---|---|---|
2 | order. | 2 | order. |
3 | 3 | ||
4 | Signed-off-by: Daniel Machon <daniel.machon@microchip.com> | 4 | Signed-off-by: Daniel Machon <daniel.machon@microchip.com> |
5 | --- | 5 | --- |
6 | .../ethernet/microchip/sparx5/sparx5_dcb.c | 105 ++++++++++++++++++ | 6 | .../ethernet/microchip/sparx5/sparx5_dcb.c | 105 ++++++++++++++++++ |
7 | .../ethernet/microchip/sparx5/sparx5_port.c | 4 +- | 7 | .../ethernet/microchip/sparx5/sparx5_port.c | 4 +- |
8 | .../ethernet/microchip/sparx5/sparx5_port.h | 2 + | 8 | .../ethernet/microchip/sparx5/sparx5_port.h | 2 + |
9 | 3 files changed, 109 insertions(+), 2 deletions(-) | 9 | 3 files changed, 109 insertions(+), 2 deletions(-) |
10 | 10 | ||
11 | diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c b/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c | 11 | diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c b/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c |
12 | index XXXXXXX..XXXXXXX 100644 | 12 | index XXXXXXX..XXXXXXX 100644 |
13 | --- a/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c | 13 | --- a/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c |
14 | +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c | 14 | +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c |
15 | @@ -XXX,XX +XXX,XX @@ | 15 | @@ -XXX,XX +XXX,XX @@ |
16 | 16 | ||
17 | #include "sparx5_port.h" | 17 | #include "sparx5_port.h" |
18 | 18 | ||
19 | +static const struct sparx5_dcb_apptrust { | 19 | +static const struct sparx5_dcb_apptrust { |
20 | + u8 selectors[256]; | 20 | + u8 selectors[256]; |
21 | + int nselectors; | 21 | + int nselectors; |
22 | + const char *names; | 22 | + const char *names; |
23 | +} *apptrust[SPX5_PORTS]; | 23 | +} *apptrust[SPX5_PORTS]; |
24 | + | 24 | + |
25 | +/* Sparx5 supported apptrust configurations */ | 25 | +/* Sparx5 supported apptrust configurations */ |
26 | +static const struct sparx5_dcb_apptrust apptrust_conf[4] = { | 26 | +static const struct sparx5_dcb_apptrust apptrust_conf[4] = { |
27 | + /* Empty *must* be first */ | 27 | + /* Empty *must* be first */ |
28 | + { { 0 }, 0, "empty" }, | 28 | + { { 0 }, 0, "empty" }, |
29 | + { { IEEE_8021QAZ_APP_SEL_DSCP }, 1, "dscp" }, | 29 | + { { IEEE_8021QAZ_APP_SEL_DSCP }, 1, "dscp" }, |
30 | + { { DCB_APP_SEL_PCP }, 1, "pcp" }, | 30 | + { { DCB_APP_SEL_PCP }, 1, "pcp" }, |
31 | + { { IEEE_8021QAZ_APP_SEL_DSCP, | 31 | + { { IEEE_8021QAZ_APP_SEL_DSCP, |
32 | + DCB_APP_SEL_PCP }, 2, "dscp pcp" }, | 32 | + DCB_APP_SEL_PCP }, 2, "dscp pcp" }, |
33 | +}; | 33 | +}; |
34 | + | 34 | + |
35 | /* Validate app entry. | 35 | /* Validate app entry. |
36 | * | 36 | * |
37 | * Check for valid selectors and valid protocol and priority ranges. | 37 | * Check for valid selectors and valid protocol and priority ranges. |
38 | @@ -XXX,XX +XXX,XX @@ static int sparx5_dcb_app_validate(struct net_device *dev, | 38 | @@ -XXX,XX +XXX,XX @@ static int sparx5_dcb_app_validate(struct net_device *dev, |
39 | return err; | 39 | return err; |
40 | } | 40 | } |
41 | 41 | ||
42 | +/* Validate apptrust configuration. | 42 | +/* Validate apptrust configuration. |
43 | + * | 43 | + * |
44 | + * Return index of supported apptrust configuration if valid, otherwise return | 44 | + * Return index of supported apptrust configuration if valid, otherwise return |
45 | + * error. | 45 | + * error. |
46 | + */ | 46 | + */ |
47 | +static int sparx5_dcb_apptrust_validate(struct net_device *dev, u8 *selectors, | 47 | +static int sparx5_dcb_apptrust_validate(struct net_device *dev, u8 *selectors, |
48 | + int nselectors, int *err) | 48 | + int nselectors, int *err) |
49 | +{ | 49 | +{ |
50 | + bool match; | 50 | + bool match; |
51 | + int i, ii; | 51 | + int i, ii; |
52 | + | 52 | + |
53 | + for (i = 0; i < ARRAY_SIZE(apptrust_conf); i++) { | 53 | + for (i = 0; i < ARRAY_SIZE(apptrust_conf); i++) { |
54 | + if (apptrust_conf[i].nselectors != nselectors) | 54 | + if (apptrust_conf[i].nselectors != nselectors) |
55 | + continue; | 55 | + continue; |
56 | + match = true; | 56 | + match = true; |
57 | + for (ii = 0; ii < nselectors; ii++) { | 57 | + for (ii = 0; ii < nselectors; ii++) { |
58 | + if (apptrust_conf[i].selectors[ii] != | 58 | + if (apptrust_conf[i].selectors[ii] != |
59 | + *(selectors + ii)) { | 59 | + *(selectors + ii)) { |
60 | + match = false; | 60 | + match = false; |
61 | + break; | 61 | + break; |
62 | + } | 62 | + } |
63 | + } | 63 | + } |
64 | + if (match) | 64 | + if (match) |
65 | + break; | 65 | + break; |
66 | + } | 66 | + } |
67 | + | 67 | + |
68 | + /* Requested trust configuration is not supported */ | 68 | + /* Requested trust configuration is not supported */ |
69 | + if (!match) { | 69 | + if (!match) { |
70 | + netdev_err(dev, "Valid apptrust configurations are:\n"); | 70 | + netdev_err(dev, "Valid apptrust configurations are:\n"); |
71 | + for (i = 0; i < ARRAY_SIZE(apptrust_conf); i++) | 71 | + for (i = 0; i < ARRAY_SIZE(apptrust_conf); i++) |
72 | + pr_info("order: %s\n", apptrust_conf[i].names); | 72 | + pr_info("order: %s\n", apptrust_conf[i].names); |
73 | + *err = -EOPNOTSUPP; | 73 | + *err = -EOPNOTSUPP; |
74 | + } | 74 | + } |
75 | + | 75 | + |
76 | + return i; | 76 | + return i; |
77 | +} | 77 | +} |
78 | + | 78 | + |
79 | +static bool sparx5_dcb_apptrust_contains(int portno, u8 selector) | 79 | +static bool sparx5_dcb_apptrust_contains(int portno, u8 selector) |
80 | +{ | 80 | +{ |
81 | + const struct sparx5_dcb_apptrust *conf = apptrust[portno]; | 81 | + const struct sparx5_dcb_apptrust *conf = apptrust[portno]; |
82 | + int i; | 82 | + int i; |
83 | + | 83 | + |
84 | + for (i = 0; i < conf->nselectors; i++) | 84 | + for (i = 0; i < conf->nselectors; i++) |
85 | + if (conf->selectors[i] == selector) | 85 | + if (conf->selectors[i] == selector) |
86 | + return true; | 86 | + return true; |
87 | + | 87 | + |
88 | + return false; | 88 | + return false; |
89 | +} | 89 | +} |
90 | + | 90 | + |
91 | static int sparx5_dcb_app_update(struct net_device *dev) | 91 | static int sparx5_dcb_app_update(struct net_device *dev) |
92 | { | 92 | { |
93 | struct dcb_app app_itr = { .selector = DCB_APP_SEL_PCP }; | 93 | struct dcb_app app_itr = { .selector = DCB_APP_SEL_PCP }; |
94 | struct sparx5_port *port = netdev_priv(dev); | 94 | struct sparx5_port *port = netdev_priv(dev); |
95 | struct sparx5_port_qos_pcp_map *pcp_map; | 95 | struct sparx5_port_qos_pcp_map *pcp_map; |
96 | struct sparx5_port_qos qos = {0}; | 96 | struct sparx5_port_qos qos = {0}; |
97 | + int portno = port->portno; | 97 | + int portno = port->portno; |
98 | int i; | 98 | int i; |
99 | 99 | ||
100 | pcp_map = &qos.pcp.map; | 100 | pcp_map = &qos.pcp.map; |
101 | @@ -XXX,XX +XXX,XX @@ static int sparx5_dcb_app_update(struct net_device *dev) | 101 | @@ -XXX,XX +XXX,XX @@ static int sparx5_dcb_app_update(struct net_device *dev) |
102 | pcp_map->map[i] = dcb_getapp(dev, &app_itr); | 102 | pcp_map->map[i] = dcb_getapp(dev, &app_itr); |
103 | } | 103 | } |
104 | 104 | ||
105 | + /* Enable use of pcp for queue classification ? */ | 105 | + /* Enable use of pcp for queue classification ? */ |
106 | + if (sparx5_dcb_apptrust_contains(portno, DCB_APP_SEL_PCP)) { | 106 | + if (sparx5_dcb_apptrust_contains(portno, DCB_APP_SEL_PCP)) { |
107 | + qos.pcp.qos_enable = true; | 107 | + qos.pcp.qos_enable = true; |
108 | + qos.pcp.dp_enable = qos.pcp.qos_enable; | 108 | + qos.pcp.dp_enable = qos.pcp.qos_enable; |
109 | + } | 109 | + } |
110 | + | 110 | + |
111 | return sparx5_port_qos_set(port, &qos); | 111 | return sparx5_port_qos_set(port, &qos); |
112 | } | 112 | } |
113 | 113 | ||
114 | @@ -XXX,XX +XXX,XX @@ static int sparx5_dcb_ieee_delapp(struct net_device *dev, struct dcb_app *app) | 114 | @@ -XXX,XX +XXX,XX @@ static int sparx5_dcb_ieee_delapp(struct net_device *dev, struct dcb_app *app) |
115 | return sparx5_dcb_app_update(dev); | 115 | return sparx5_dcb_app_update(dev); |
116 | } | 116 | } |
117 | 117 | ||
118 | +static int sparx5_dcb_setapptrust(struct net_device *dev, u8 *selectors, | 118 | +static int sparx5_dcb_setapptrust(struct net_device *dev, u8 *selectors, |
119 | + int nselectors) | 119 | + int nselectors) |
120 | +{ | 120 | +{ |
121 | + struct sparx5_port *port = netdev_priv(dev); | 121 | + struct sparx5_port *port = netdev_priv(dev); |
122 | + int err = 0, idx; | 122 | + int err = 0, idx; |
123 | + | 123 | + |
124 | + idx = sparx5_dcb_apptrust_validate(dev, selectors, nselectors, &err); | 124 | + idx = sparx5_dcb_apptrust_validate(dev, selectors, nselectors, &err); |
125 | + if (err < 0) | 125 | + if (err < 0) |
126 | + return err; | 126 | + return err; |
127 | + | 127 | + |
128 | + apptrust[port->portno] = &apptrust_conf[idx]; | 128 | + apptrust[port->portno] = &apptrust_conf[idx]; |
129 | + | 129 | + |
130 | + return sparx5_dcb_app_update(dev); | 130 | + return sparx5_dcb_app_update(dev); |
131 | +} | 131 | +} |
132 | + | 132 | + |
133 | +static int sparx5_dcb_getapptrust(struct net_device *dev, u8 *selectors, | 133 | +static int sparx5_dcb_getapptrust(struct net_device *dev, u8 *selectors, |
134 | + int *nselectors) | 134 | + int *nselectors) |
135 | +{ | 135 | +{ |
136 | + struct sparx5_port *port = netdev_priv(dev); | 136 | + struct sparx5_port *port = netdev_priv(dev); |
137 | + const struct sparx5_dcb_apptrust *trust; | 137 | + const struct sparx5_dcb_apptrust *trust; |
138 | + | 138 | + |
139 | + trust = apptrust[port->portno]; | 139 | + trust = apptrust[port->portno]; |
140 | + | 140 | + |
141 | + memcpy(selectors, trust->selectors, trust->nselectors); | 141 | + memcpy(selectors, trust->selectors, trust->nselectors); |
142 | + *nselectors = trust->nselectors; | 142 | + *nselectors = trust->nselectors; |
143 | + | 143 | + |
144 | + return 0; | 144 | + return 0; |
145 | +} | 145 | +} |
146 | + | 146 | + |
147 | const struct dcbnl_rtnl_ops sparx5_dcbnl_ops = { | 147 | const struct dcbnl_rtnl_ops sparx5_dcbnl_ops = { |
148 | .ieee_setapp = sparx5_dcb_ieee_setapp, | 148 | .ieee_setapp = sparx5_dcb_ieee_setapp, |
149 | .ieee_delapp = sparx5_dcb_ieee_delapp, | 149 | .ieee_delapp = sparx5_dcb_ieee_delapp, |
150 | + .dcbnl_setapptrust = sparx5_dcb_setapptrust, | 150 | + .dcbnl_setapptrust = sparx5_dcb_setapptrust, |
151 | + .dcbnl_getapptrust = sparx5_dcb_getapptrust, | 151 | + .dcbnl_getapptrust = sparx5_dcb_getapptrust, |
152 | }; | 152 | }; |
153 | 153 | ||
154 | int sparx5_dcb_init(struct sparx5 *sparx5) | 154 | int sparx5_dcb_init(struct sparx5 *sparx5) |
155 | @@ -XXX,XX +XXX,XX @@ int sparx5_dcb_init(struct sparx5 *sparx5) | 155 | @@ -XXX,XX +XXX,XX @@ int sparx5_dcb_init(struct sparx5 *sparx5) |
156 | if (!port) | 156 | if (!port) |
157 | continue; | 157 | continue; |
158 | port->ndev->dcbnl_ops = &sparx5_dcbnl_ops; | 158 | port->ndev->dcbnl_ops = &sparx5_dcbnl_ops; |
159 | + /* Initialize [dscp, pcp] default trust */ | 159 | + /* Initialize [dscp, pcp] default trust */ |
160 | + apptrust[port->portno] = &apptrust_conf[3]; | 160 | + apptrust[port->portno] = &apptrust_conf[3]; |
161 | } | 161 | } |
162 | 162 | ||
163 | return 0; | 163 | return 0; |
164 | diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c | 164 | diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c |
165 | index XXXXXXX..XXXXXXX 100644 | 165 | index XXXXXXX..XXXXXXX 100644 |
166 | --- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c | 166 | --- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c |
167 | +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c | 167 | +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c |
168 | @@ -XXX,XX +XXX,XX @@ int sparx5_port_qos_pcp_set(const struct sparx5_port *port, | 168 | @@ -XXX,XX +XXX,XX @@ int sparx5_port_qos_pcp_set(const struct sparx5_port *port, |
169 | int i; | 169 | int i; |
170 | 170 | ||
171 | /* Enable/disable pcp and dp for qos classification. */ | 171 | /* Enable/disable pcp and dp for qos classification. */ |
172 | - spx5_rmw(ANA_CL_QOS_CFG_PCP_DEI_QOS_ENA_SET(1) | | 172 | - spx5_rmw(ANA_CL_QOS_CFG_PCP_DEI_QOS_ENA_SET(1) | |
173 | - ANA_CL_QOS_CFG_PCP_DEI_DP_ENA_SET(1), | 173 | - ANA_CL_QOS_CFG_PCP_DEI_DP_ENA_SET(1), |
174 | + spx5_rmw(ANA_CL_QOS_CFG_PCP_DEI_QOS_ENA_SET(qos->qos_enable) | | 174 | + spx5_rmw(ANA_CL_QOS_CFG_PCP_DEI_QOS_ENA_SET(qos->qos_enable) | |
175 | + ANA_CL_QOS_CFG_PCP_DEI_DP_ENA_SET(qos->dp_enable), | 175 | + ANA_CL_QOS_CFG_PCP_DEI_DP_ENA_SET(qos->dp_enable), |
176 | ANA_CL_QOS_CFG_PCP_DEI_QOS_ENA | ANA_CL_QOS_CFG_PCP_DEI_DP_ENA, | 176 | ANA_CL_QOS_CFG_PCP_DEI_QOS_ENA | ANA_CL_QOS_CFG_PCP_DEI_DP_ENA, |
177 | sparx5, ANA_CL_QOS_CFG(port->portno)); | 177 | sparx5, ANA_CL_QOS_CFG(port->portno)); |
178 | 178 | ||
179 | diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.h b/drivers/net/ethernet/microchip/sparx5/sparx5_port.h | 179 | diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.h b/drivers/net/ethernet/microchip/sparx5/sparx5_port.h |
180 | index XXXXXXX..XXXXXXX 100644 | 180 | index XXXXXXX..XXXXXXX 100644 |
181 | --- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.h | 181 | --- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.h |
182 | +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.h | 182 | +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.h |
183 | @@ -XXX,XX +XXX,XX @@ struct sparx5_port_qos_pcp_map { | 183 | @@ -XXX,XX +XXX,XX @@ struct sparx5_port_qos_pcp_map { |
184 | 184 | ||
185 | struct sparx5_port_qos_pcp { | 185 | struct sparx5_port_qos_pcp { |
186 | struct sparx5_port_qos_pcp_map map; | 186 | struct sparx5_port_qos_pcp_map map; |
187 | + bool qos_enable; | 187 | + bool qos_enable; |
188 | + bool dp_enable; | 188 | + bool dp_enable; |
189 | }; | 189 | }; |
190 | 190 | ||
191 | struct sparx5_port_qos { | 191 | struct sparx5_port_qos { |
192 | -- | 192 | -- |
193 | 2.34.1 | 193 | 2.34.1 | diff view generated by jsdifflib |
1 | Add support for offloading dscp app entries. Dscp values are global for | 1 | Add support for offloading dscp app entries. Dscp values are global for |
---|---|---|---|
2 | all ports on the sparx5 switch. Therefore, we replicate each dscp app | 2 | all ports on the sparx5 switch. Therefore, we replicate each dscp app |
3 | entry per-port. | 3 | entry per-port. |
4 | 4 | ||
5 | Signed-off-by: Daniel Machon <daniel.machon@microchip.com> | 5 | Signed-off-by: Daniel Machon <daniel.machon@microchip.com> |
6 | --- | 6 | --- |
7 | .../ethernet/microchip/sparx5/sparx5_dcb.c | 66 ++++++++++++++++++- | 7 | .../ethernet/microchip/sparx5/sparx5_dcb.c | 66 ++++++++++++++++++- |
8 | .../ethernet/microchip/sparx5/sparx5_port.c | 39 +++++++++++ | 8 | .../ethernet/microchip/sparx5/sparx5_port.c | 39 +++++++++++ |
9 | .../ethernet/microchip/sparx5/sparx5_port.h | 13 ++++ | 9 | .../ethernet/microchip/sparx5/sparx5_port.h | 13 ++++ |
10 | 3 files changed, 115 insertions(+), 3 deletions(-) | 10 | 3 files changed, 115 insertions(+), 3 deletions(-) |
11 | 11 | ||
12 | diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c b/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c | 12 | diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c b/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c |
13 | index XXXXXXX..XXXXXXX 100644 | 13 | index XXXXXXX..XXXXXXX 100644 |
14 | --- a/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c | 14 | --- a/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c |
15 | +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c | 15 | +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c |
16 | @@ -XXX,XX +XXX,XX @@ static int sparx5_dcb_app_validate(struct net_device *dev, | 16 | @@ -XXX,XX +XXX,XX @@ static int sparx5_dcb_app_validate(struct net_device *dev, |
17 | int err = 0; | 17 | int err = 0; |
18 | 18 | ||
19 | switch (app->selector) { | 19 | switch (app->selector) { |
20 | + /* Dscp checks */ | 20 | + /* Dscp checks */ |
21 | + case IEEE_8021QAZ_APP_SEL_DSCP: | 21 | + case IEEE_8021QAZ_APP_SEL_DSCP: |
22 | + if (app->protocol > 63) | 22 | + if (app->protocol > 63) |
23 | + err = -EINVAL; | 23 | + err = -EINVAL; |
24 | + else if (app->priority >= SPX5_PRIOS) | 24 | + else if (app->priority >= SPX5_PRIOS) |
25 | + err = -ERANGE; | 25 | + err = -ERANGE; |
26 | + break; | 26 | + break; |
27 | /* Pcp checks */ | 27 | /* Pcp checks */ |
28 | case DCB_APP_SEL_PCP: | 28 | case DCB_APP_SEL_PCP: |
29 | if (app->protocol > 15) | 29 | if (app->protocol > 15) |
30 | @@ -XXX,XX +XXX,XX @@ static bool sparx5_dcb_apptrust_contains(int portno, u8 selector) | 30 | @@ -XXX,XX +XXX,XX @@ static bool sparx5_dcb_apptrust_contains(int portno, u8 selector) |
31 | 31 | ||
32 | static int sparx5_dcb_app_update(struct net_device *dev) | 32 | static int sparx5_dcb_app_update(struct net_device *dev) |
33 | { | 33 | { |
34 | - struct dcb_app app_itr = { .selector = DCB_APP_SEL_PCP }; | 34 | - struct dcb_app app_itr = { .selector = DCB_APP_SEL_PCP }; |
35 | struct sparx5_port *port = netdev_priv(dev); | 35 | struct sparx5_port *port = netdev_priv(dev); |
36 | + struct sparx5_port_qos_dscp_map *dscp_map; | 36 | + struct sparx5_port_qos_dscp_map *dscp_map; |
37 | struct sparx5_port_qos_pcp_map *pcp_map; | 37 | struct sparx5_port_qos_pcp_map *pcp_map; |
38 | struct sparx5_port_qos qos = {0}; | 38 | struct sparx5_port_qos qos = {0}; |
39 | + struct dcb_app app_itr = {0}; | 39 | + struct dcb_app app_itr = {0}; |
40 | int portno = port->portno; | 40 | int portno = port->portno; |
41 | int i; | 41 | int i; |
42 | 42 | ||
43 | + dscp_map = &qos.dscp.map; | 43 | + dscp_map = &qos.dscp.map; |
44 | pcp_map = &qos.pcp.map; | 44 | pcp_map = &qos.pcp.map; |
45 | 45 | ||
46 | + /* Get dscp ingress mapping */ | 46 | + /* Get dscp ingress mapping */ |
47 | + for (i = 0; i < ARRAY_SIZE(dscp_map->map); i++) { | 47 | + for (i = 0; i < ARRAY_SIZE(dscp_map->map); i++) { |
48 | + app_itr.selector = IEEE_8021QAZ_APP_SEL_DSCP; | 48 | + app_itr.selector = IEEE_8021QAZ_APP_SEL_DSCP; |
49 | + app_itr.protocol = i; | 49 | + app_itr.protocol = i; |
50 | + dscp_map->map[i] = dcb_getapp(dev, &app_itr); | 50 | + dscp_map->map[i] = dcb_getapp(dev, &app_itr); |
51 | + } | 51 | + } |
52 | + | 52 | + |
53 | /* Get pcp ingress mapping */ | 53 | /* Get pcp ingress mapping */ |
54 | for (i = 0; i < ARRAY_SIZE(pcp_map->map); i++) { | 54 | for (i = 0; i < ARRAY_SIZE(pcp_map->map); i++) { |
55 | + app_itr.selector = DCB_APP_SEL_PCP; | 55 | + app_itr.selector = DCB_APP_SEL_PCP; |
56 | app_itr.protocol = i; | 56 | app_itr.protocol = i; |
57 | pcp_map->map[i] = dcb_getapp(dev, &app_itr); | 57 | pcp_map->map[i] = dcb_getapp(dev, &app_itr); |
58 | } | 58 | } |
59 | @@ -XXX,XX +XXX,XX @@ static int sparx5_dcb_app_update(struct net_device *dev) | 59 | @@ -XXX,XX +XXX,XX @@ static int sparx5_dcb_app_update(struct net_device *dev) |
60 | qos.pcp.dp_enable = qos.pcp.qos_enable; | 60 | qos.pcp.dp_enable = qos.pcp.qos_enable; |
61 | } | 61 | } |
62 | 62 | ||
63 | + /* Enable use of dscp for queue classification ? */ | 63 | + /* Enable use of dscp for queue classification ? */ |
64 | + if (sparx5_dcb_apptrust_contains(portno, IEEE_8021QAZ_APP_SEL_DSCP)) { | 64 | + if (sparx5_dcb_apptrust_contains(portno, IEEE_8021QAZ_APP_SEL_DSCP)) { |
65 | + qos.dscp.qos_enable = true; | 65 | + qos.dscp.qos_enable = true; |
66 | + qos.dscp.dp_enable = qos.dscp.qos_enable; | 66 | + qos.dscp.dp_enable = qos.dscp.qos_enable; |
67 | + } | 67 | + } |
68 | + | 68 | + |
69 | return sparx5_port_qos_set(port, &qos); | 69 | return sparx5_port_qos_set(port, &qos); |
70 | } | 70 | } |
71 | 71 | ||
72 | +/* Set or delete dscp app entry. | 72 | +/* Set or delete dscp app entry. |
73 | + * | 73 | + * |
74 | + * Dscp mapping is global for all ports, so set and delete app entries are | 74 | + * Dscp mapping is global for all ports, so set and delete app entries are |
75 | + * replicated for each port. | 75 | + * replicated for each port. |
76 | + */ | 76 | + */ |
77 | +static int sparx5_dcb_ieee_dscp_setdel_app(struct net_device *dev, | 77 | +static int sparx5_dcb_ieee_dscp_setdel_app(struct net_device *dev, |
78 | + struct dcb_app *app, bool del) | 78 | + struct dcb_app *app, bool del) |
79 | +{ | 79 | +{ |
80 | + struct sparx5_port *port = netdev_priv(dev); | 80 | + struct sparx5_port *port = netdev_priv(dev); |
81 | + struct dcb_app apps[SPX5_PORTS]; | 81 | + struct dcb_app apps[SPX5_PORTS]; |
82 | + struct sparx5_port *port_itr; | 82 | + struct sparx5_port *port_itr; |
83 | + int err, i; | 83 | + int err, i; |
84 | + | 84 | + |
85 | + for (i = 0; i < SPX5_PORTS; i++) { | 85 | + for (i = 0; i < SPX5_PORTS; i++) { |
86 | + port_itr = port->sparx5->ports[i]; | 86 | + port_itr = port->sparx5->ports[i]; |
87 | + if (!port_itr) | 87 | + if (!port_itr) |
88 | + continue; | 88 | + continue; |
89 | + memcpy(&apps[i], app, sizeof(struct dcb_app)); | 89 | + memcpy(&apps[i], app, sizeof(struct dcb_app)); |
90 | + if (del) | 90 | + if (del) |
91 | + err = dcb_ieee_delapp(port_itr->ndev, &apps[i]); | 91 | + err = dcb_ieee_delapp(port_itr->ndev, &apps[i]); |
92 | + else | 92 | + else |
93 | + err = dcb_ieee_setapp(port_itr->ndev, &apps[i]); | 93 | + err = dcb_ieee_setapp(port_itr->ndev, &apps[i]); |
94 | + if (err) | 94 | + if (err) |
95 | + return err; | 95 | + return err; |
96 | + } | 96 | + } |
97 | + | 97 | + |
98 | + return 0; | 98 | + return 0; |
99 | +} | 99 | +} |
100 | + | 100 | + |
101 | static int sparx5_dcb_ieee_setapp(struct net_device *dev, struct dcb_app *app) | 101 | static int sparx5_dcb_ieee_setapp(struct net_device *dev, struct dcb_app *app) |
102 | { | 102 | { |
103 | struct dcb_app app_itr; | 103 | struct dcb_app app_itr; |
104 | @@ -XXX,XX +XXX,XX @@ static int sparx5_dcb_ieee_setapp(struct net_device *dev, struct dcb_app *app) | 104 | @@ -XXX,XX +XXX,XX @@ static int sparx5_dcb_ieee_setapp(struct net_device *dev, struct dcb_app *app) |
105 | dcb_ieee_delapp(dev, &app_itr); | 105 | dcb_ieee_delapp(dev, &app_itr); |
106 | } | 106 | } |
107 | 107 | ||
108 | - err = dcb_ieee_setapp(dev, app); | 108 | - err = dcb_ieee_setapp(dev, app); |
109 | + if (app->selector == IEEE_8021QAZ_APP_SEL_DSCP) | 109 | + if (app->selector == IEEE_8021QAZ_APP_SEL_DSCP) |
110 | + err = sparx5_dcb_ieee_dscp_setdel_app(dev, app, false); | 110 | + err = sparx5_dcb_ieee_dscp_setdel_app(dev, app, false); |
111 | + else | 111 | + else |
112 | + err = dcb_ieee_setapp(dev, app); | 112 | + err = dcb_ieee_setapp(dev, app); |
113 | + | 113 | + |
114 | if (err) | 114 | if (err) |
115 | goto out; | 115 | goto out; |
116 | 116 | ||
117 | @@ -XXX,XX +XXX,XX @@ static int sparx5_dcb_ieee_delapp(struct net_device *dev, struct dcb_app *app) | 117 | @@ -XXX,XX +XXX,XX @@ static int sparx5_dcb_ieee_delapp(struct net_device *dev, struct dcb_app *app) |
118 | { | 118 | { |
119 | int err; | 119 | int err; |
120 | 120 | ||
121 | - err = dcb_ieee_delapp(dev, app); | 121 | - err = dcb_ieee_delapp(dev, app); |
122 | + if (app->selector == IEEE_8021QAZ_APP_SEL_DSCP) | 122 | + if (app->selector == IEEE_8021QAZ_APP_SEL_DSCP) |
123 | + err = sparx5_dcb_ieee_dscp_setdel_app(dev, app, true); | 123 | + err = sparx5_dcb_ieee_dscp_setdel_app(dev, app, true); |
124 | + else | 124 | + else |
125 | + err = dcb_ieee_delapp(dev, app); | 125 | + err = dcb_ieee_delapp(dev, app); |
126 | + | 126 | + |
127 | if (err < 0) | 127 | if (err < 0) |
128 | return err; | 128 | return err; |
129 | 129 | ||
130 | diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c | 130 | diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c |
131 | index XXXXXXX..XXXXXXX 100644 | 131 | index XXXXXXX..XXXXXXX 100644 |
132 | --- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c | 132 | --- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c |
133 | +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c | 133 | +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c |
134 | @@ -XXX,XX +XXX,XX @@ void sparx5_port_enable(struct sparx5_port *port, bool enable) | 134 | @@ -XXX,XX +XXX,XX @@ void sparx5_port_enable(struct sparx5_port *port, bool enable) |
135 | int sparx5_port_qos_set(struct sparx5_port *port, | 135 | int sparx5_port_qos_set(struct sparx5_port *port, |
136 | struct sparx5_port_qos *qos) | 136 | struct sparx5_port_qos *qos) |
137 | { | 137 | { |
138 | + sparx5_port_qos_dscp_set(port, &qos->dscp); | 138 | + sparx5_port_qos_dscp_set(port, &qos->dscp); |
139 | sparx5_port_qos_pcp_set(port, &qos->pcp); | 139 | sparx5_port_qos_pcp_set(port, &qos->pcp); |
140 | 140 | ||
141 | return 0; | 141 | return 0; |
142 | @@ -XXX,XX +XXX,XX @@ int sparx5_port_qos_pcp_set(const struct sparx5_port *port, | 142 | @@ -XXX,XX +XXX,XX @@ int sparx5_port_qos_pcp_set(const struct sparx5_port *port, |
143 | 143 | ||
144 | return 0; | 144 | return 0; |
145 | } | 145 | } |
146 | + | 146 | + |
147 | +int sparx5_port_qos_dscp_set(const struct sparx5_port *port, | 147 | +int sparx5_port_qos_dscp_set(const struct sparx5_port *port, |
148 | + struct sparx5_port_qos_dscp *qos) | 148 | + struct sparx5_port_qos_dscp *qos) |
149 | +{ | 149 | +{ |
150 | + struct sparx5 *sparx5 = port->sparx5; | 150 | + struct sparx5 *sparx5 = port->sparx5; |
151 | + u8 *dscp = qos->map.map; | 151 | + u8 *dscp = qos->map.map; |
152 | + int i; | 152 | + int i; |
153 | + | 153 | + |
154 | + /* Enable/disable dscp and dp for qos classification. | 154 | + /* Enable/disable dscp and dp for qos classification. |
155 | + * Disable rewrite of dscp values for now. | 155 | + * Disable rewrite of dscp values for now. |
156 | + */ | 156 | + */ |
157 | + spx5_rmw(ANA_CL_QOS_CFG_DSCP_QOS_ENA_SET(qos->qos_enable) | | 157 | + spx5_rmw(ANA_CL_QOS_CFG_DSCP_QOS_ENA_SET(qos->qos_enable) | |
158 | + ANA_CL_QOS_CFG_DSCP_DP_ENA_SET(qos->dp_enable) | | 158 | + ANA_CL_QOS_CFG_DSCP_DP_ENA_SET(qos->dp_enable) | |
159 | + ANA_CL_QOS_CFG_DSCP_KEEP_ENA_SET(1), | 159 | + ANA_CL_QOS_CFG_DSCP_KEEP_ENA_SET(1), |
160 | + ANA_CL_QOS_CFG_DSCP_QOS_ENA | ANA_CL_QOS_CFG_DSCP_DP_ENA | | 160 | + ANA_CL_QOS_CFG_DSCP_QOS_ENA | ANA_CL_QOS_CFG_DSCP_DP_ENA | |
161 | + ANA_CL_QOS_CFG_DSCP_KEEP_ENA, sparx5, | 161 | + ANA_CL_QOS_CFG_DSCP_KEEP_ENA, sparx5, |
162 | + ANA_CL_QOS_CFG(port->portno)); | 162 | + ANA_CL_QOS_CFG(port->portno)); |
163 | + | 163 | + |
164 | + /* Map each dscp value to priority and dp */ | 164 | + /* Map each dscp value to priority and dp */ |
165 | + for (i = 0; i < ARRAY_SIZE(qos->map.map); i++) { | 165 | + for (i = 0; i < ARRAY_SIZE(qos->map.map); i++) { |
166 | + spx5_rmw(ANA_CL_DSCP_CFG_DSCP_QOS_VAL_SET(*(dscp + i)) | | 166 | + spx5_rmw(ANA_CL_DSCP_CFG_DSCP_QOS_VAL_SET(*(dscp + i)) | |
167 | + ANA_CL_DSCP_CFG_DSCP_DP_VAL_SET(0), | 167 | + ANA_CL_DSCP_CFG_DSCP_DP_VAL_SET(0), |
168 | + ANA_CL_DSCP_CFG_DSCP_QOS_VAL | | 168 | + ANA_CL_DSCP_CFG_DSCP_QOS_VAL | |
169 | + ANA_CL_DSCP_CFG_DSCP_DP_VAL, sparx5, | 169 | + ANA_CL_DSCP_CFG_DSCP_DP_VAL, sparx5, |
170 | + ANA_CL_DSCP_CFG(i)); | 170 | + ANA_CL_DSCP_CFG(i)); |
171 | + } | 171 | + } |
172 | + | 172 | + |
173 | + /* Set per-dscp trust */ | 173 | + /* Set per-dscp trust */ |
174 | + for (i = 0; i < ARRAY_SIZE(qos->map.map); i++) { | 174 | + for (i = 0; i < ARRAY_SIZE(qos->map.map); i++) { |
175 | + if (qos->qos_enable) { | 175 | + if (qos->qos_enable) { |
176 | + spx5_rmw(ANA_CL_DSCP_CFG_DSCP_TRUST_ENA_SET(1), | 176 | + spx5_rmw(ANA_CL_DSCP_CFG_DSCP_TRUST_ENA_SET(1), |
177 | + ANA_CL_DSCP_CFG_DSCP_TRUST_ENA, sparx5, | 177 | + ANA_CL_DSCP_CFG_DSCP_TRUST_ENA, sparx5, |
178 | + ANA_CL_DSCP_CFG(i)); | 178 | + ANA_CL_DSCP_CFG(i)); |
179 | + } | 179 | + } |
180 | + } | 180 | + } |
181 | + | 181 | + |
182 | + return 0; | 182 | + return 0; |
183 | +} | 183 | +} |
184 | diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.h b/drivers/net/ethernet/microchip/sparx5/sparx5_port.h | 184 | diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.h b/drivers/net/ethernet/microchip/sparx5/sparx5_port.h |
185 | index XXXXXXX..XXXXXXX 100644 | 185 | index XXXXXXX..XXXXXXX 100644 |
186 | --- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.h | 186 | --- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.h |
187 | +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.h | 187 | +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.h |
188 | @@ -XXX,XX +XXX,XX @@ struct sparx5_port_qos_pcp_map { | 188 | @@ -XXX,XX +XXX,XX @@ struct sparx5_port_qos_pcp_map { |
189 | u8 map[16]; | 189 | u8 map[16]; |
190 | }; | 190 | }; |
191 | 191 | ||
192 | +struct sparx5_port_qos_dscp_map { | 192 | +struct sparx5_port_qos_dscp_map { |
193 | + u8 map[64]; | 193 | + u8 map[64]; |
194 | +}; | 194 | +}; |
195 | + | 195 | + |
196 | struct sparx5_port_qos_pcp { | 196 | struct sparx5_port_qos_pcp { |
197 | struct sparx5_port_qos_pcp_map map; | 197 | struct sparx5_port_qos_pcp_map map; |
198 | bool qos_enable; | 198 | bool qos_enable; |
199 | bool dp_enable; | 199 | bool dp_enable; |
200 | }; | 200 | }; |
201 | 201 | ||
202 | +struct sparx5_port_qos_dscp { | 202 | +struct sparx5_port_qos_dscp { |
203 | + struct sparx5_port_qos_dscp_map map; | 203 | + struct sparx5_port_qos_dscp_map map; |
204 | + bool qos_enable; | 204 | + bool qos_enable; |
205 | + bool dp_enable; | 205 | + bool dp_enable; |
206 | +}; | 206 | +}; |
207 | + | 207 | + |
208 | struct sparx5_port_qos { | 208 | struct sparx5_port_qos { |
209 | struct sparx5_port_qos_pcp pcp; | 209 | struct sparx5_port_qos_pcp pcp; |
210 | + struct sparx5_port_qos_dscp dscp; | 210 | + struct sparx5_port_qos_dscp dscp; |
211 | }; | 211 | }; |
212 | 212 | ||
213 | int sparx5_port_qos_set(struct sparx5_port *port, struct sparx5_port_qos *qos); | 213 | int sparx5_port_qos_set(struct sparx5_port *port, struct sparx5_port_qos *qos); |
214 | @@ -XXX,XX +XXX,XX @@ int sparx5_port_qos_set(struct sparx5_port *port, struct sparx5_port_qos *qos); | 214 | @@ -XXX,XX +XXX,XX @@ int sparx5_port_qos_set(struct sparx5_port *port, struct sparx5_port_qos *qos); |
215 | int sparx5_port_qos_pcp_set(const struct sparx5_port *port, | 215 | int sparx5_port_qos_pcp_set(const struct sparx5_port *port, |
216 | struct sparx5_port_qos_pcp *qos); | 216 | struct sparx5_port_qos_pcp *qos); |
217 | 217 | ||
218 | +int sparx5_port_qos_dscp_set(const struct sparx5_port *port, | 218 | +int sparx5_port_qos_dscp_set(const struct sparx5_port *port, |
219 | + struct sparx5_port_qos_dscp *qos); | 219 | + struct sparx5_port_qos_dscp *qos); |
220 | #endif /* __SPARX5_PORT_H__ */ | 220 | #endif /* __SPARX5_PORT_H__ */ |
221 | -- | 221 | -- |
222 | 2.34.1 | 222 | 2.34.1 | diff view generated by jsdifflib |
1 | Add support for offloading default prio {ETHERTYPE, 0, prio}. | 1 | Add support for offloading default prio {ETHERTYPE, 0, prio}. |
---|---|---|---|
2 | 2 | ||
3 | Signed-off-by: Daniel Machon <daniel.machon@microchip.com> | 3 | Signed-off-by: Daniel Machon <daniel.machon@microchip.com> |
4 | --- | 4 | --- |
5 | .../ethernet/microchip/sparx5/sparx5_dcb.c | 12 ++++++++++ | 5 | .../ethernet/microchip/sparx5/sparx5_dcb.c | 12 ++++++++++ |
6 | .../ethernet/microchip/sparx5/sparx5_port.c | 23 +++++++++++++++++++ | 6 | .../ethernet/microchip/sparx5/sparx5_port.c | 23 +++++++++++++++++++ |
7 | .../ethernet/microchip/sparx5/sparx5_port.h | 5 ++++ | 7 | .../ethernet/microchip/sparx5/sparx5_port.h | 5 ++++ |
8 | 3 files changed, 40 insertions(+) | 8 | 3 files changed, 40 insertions(+) |
9 | 9 | ||
10 | diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c b/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c | 10 | diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c b/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c |
11 | index XXXXXXX..XXXXXXX 100644 | 11 | index XXXXXXX..XXXXXXX 100644 |
12 | --- a/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c | 12 | --- a/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c |
13 | +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c | 13 | +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c |
14 | @@ -XXX,XX +XXX,XX @@ static int sparx5_dcb_app_validate(struct net_device *dev, | 14 | @@ -XXX,XX +XXX,XX @@ static int sparx5_dcb_app_validate(struct net_device *dev, |
15 | int err = 0; | 15 | int err = 0; |
16 | 16 | ||
17 | switch (app->selector) { | 17 | switch (app->selector) { |
18 | + /* Default priority checks */ | 18 | + /* Default priority checks */ |
19 | + case IEEE_8021QAZ_APP_SEL_ETHERTYPE: | 19 | + case IEEE_8021QAZ_APP_SEL_ETHERTYPE: |
20 | + if (app->protocol != 0) | 20 | + if (app->protocol != 0) |
21 | + err = -EINVAL; | 21 | + err = -EINVAL; |
22 | + else if (app->priority >= SPX5_PRIOS) | 22 | + else if (app->priority >= SPX5_PRIOS) |
23 | + err = -ERANGE; | 23 | + err = -ERANGE; |
24 | + break; | 24 | + break; |
25 | /* Dscp checks */ | 25 | /* Dscp checks */ |
26 | case IEEE_8021QAZ_APP_SEL_DSCP: | 26 | case IEEE_8021QAZ_APP_SEL_DSCP: |
27 | if (app->protocol > 63) | 27 | if (app->protocol > 63) |
28 | @@ -XXX,XX +XXX,XX @@ static int sparx5_dcb_app_update(struct net_device *dev) | 28 | @@ -XXX,XX +XXX,XX @@ static int sparx5_dcb_app_update(struct net_device *dev) |
29 | dscp_map = &qos.dscp.map; | 29 | dscp_map = &qos.dscp.map; |
30 | pcp_map = &qos.pcp.map; | 30 | pcp_map = &qos.pcp.map; |
31 | 31 | ||
32 | + /* Get default prio. */ | 32 | + /* Get default prio. */ |
33 | + qos.default_prio = dcb_ieee_getapp_default_prio_mask(dev); | 33 | + qos.default_prio = dcb_ieee_getapp_default_prio_mask(dev); |
34 | + if (qos.default_prio) | 34 | + if (qos.default_prio) |
35 | + qos.default_prio = fls(qos.default_prio) - 1; | 35 | + qos.default_prio = fls(qos.default_prio) - 1; |
36 | + | 36 | + |
37 | /* Get dscp ingress mapping */ | 37 | /* Get dscp ingress mapping */ |
38 | for (i = 0; i < ARRAY_SIZE(dscp_map->map); i++) { | 38 | for (i = 0; i < ARRAY_SIZE(dscp_map->map); i++) { |
39 | app_itr.selector = IEEE_8021QAZ_APP_SEL_DSCP; | 39 | app_itr.selector = IEEE_8021QAZ_APP_SEL_DSCP; |
40 | diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c | 40 | diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c |
41 | index XXXXXXX..XXXXXXX 100644 | 41 | index XXXXXXX..XXXXXXX 100644 |
42 | --- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c | 42 | --- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c |
43 | +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c | 43 | +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c |
44 | @@ -XXX,XX +XXX,XX @@ int sparx5_port_qos_set(struct sparx5_port *port, | 44 | @@ -XXX,XX +XXX,XX @@ int sparx5_port_qos_set(struct sparx5_port *port, |
45 | { | 45 | { |
46 | sparx5_port_qos_dscp_set(port, &qos->dscp); | 46 | sparx5_port_qos_dscp_set(port, &qos->dscp); |
47 | sparx5_port_qos_pcp_set(port, &qos->pcp); | 47 | sparx5_port_qos_pcp_set(port, &qos->pcp); |
48 | + sparx5_port_qos_default_set(port, qos); | 48 | + sparx5_port_qos_default_set(port, qos); |
49 | 49 | ||
50 | return 0; | 50 | return 0; |
51 | } | 51 | } |
52 | @@ -XXX,XX +XXX,XX @@ int sparx5_port_qos_dscp_set(const struct sparx5_port *port, | 52 | @@ -XXX,XX +XXX,XX @@ int sparx5_port_qos_dscp_set(const struct sparx5_port *port, |
53 | 53 | ||
54 | return 0; | 54 | return 0; |
55 | } | 55 | } |
56 | + | 56 | + |
57 | +int sparx5_port_qos_default_set(const struct sparx5_port *port, | 57 | +int sparx5_port_qos_default_set(const struct sparx5_port *port, |
58 | + const struct sparx5_port_qos *qos) | 58 | + const struct sparx5_port_qos *qos) |
59 | +{ | 59 | +{ |
60 | + struct sparx5 *sparx5 = port->sparx5; | 60 | + struct sparx5 *sparx5 = port->sparx5; |
61 | + | 61 | + |
62 | + /* Set default prio and dp level */ | 62 | + /* Set default prio and dp level */ |
63 | + spx5_rmw(ANA_CL_QOS_CFG_DEFAULT_QOS_VAL_SET(qos->default_prio) | | 63 | + spx5_rmw(ANA_CL_QOS_CFG_DEFAULT_QOS_VAL_SET(qos->default_prio) | |
64 | + ANA_CL_QOS_CFG_DEFAULT_DP_VAL_SET(0), | 64 | + ANA_CL_QOS_CFG_DEFAULT_DP_VAL_SET(0), |
65 | + ANA_CL_QOS_CFG_DEFAULT_QOS_VAL | | 65 | + ANA_CL_QOS_CFG_DEFAULT_QOS_VAL | |
66 | + ANA_CL_QOS_CFG_DEFAULT_DP_VAL, | 66 | + ANA_CL_QOS_CFG_DEFAULT_DP_VAL, |
67 | + sparx5, ANA_CL_QOS_CFG(port->portno)); | 67 | + sparx5, ANA_CL_QOS_CFG(port->portno)); |
68 | + | 68 | + |
69 | + /* Set default pcp and dei for untagged frames */ | 69 | + /* Set default pcp and dei for untagged frames */ |
70 | + spx5_rmw(ANA_CL_VLAN_CTRL_PORT_PCP_SET(0) | | 70 | + spx5_rmw(ANA_CL_VLAN_CTRL_PORT_PCP_SET(0) | |
71 | + ANA_CL_VLAN_CTRL_PORT_DEI_SET(0), | 71 | + ANA_CL_VLAN_CTRL_PORT_DEI_SET(0), |
72 | + ANA_CL_VLAN_CTRL_PORT_PCP | | 72 | + ANA_CL_VLAN_CTRL_PORT_PCP | |
73 | + ANA_CL_VLAN_CTRL_PORT_DEI, | 73 | + ANA_CL_VLAN_CTRL_PORT_DEI, |
74 | + sparx5, ANA_CL_VLAN_CTRL(port->portno)); | 74 | + sparx5, ANA_CL_VLAN_CTRL(port->portno)); |
75 | + | 75 | + |
76 | + return 0; | 76 | + return 0; |
77 | +} | 77 | +} |
78 | diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.h b/drivers/net/ethernet/microchip/sparx5/sparx5_port.h | 78 | diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.h b/drivers/net/ethernet/microchip/sparx5/sparx5_port.h |
79 | index XXXXXXX..XXXXXXX 100644 | 79 | index XXXXXXX..XXXXXXX 100644 |
80 | --- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.h | 80 | --- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.h |
81 | +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.h | 81 | +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.h |
82 | @@ -XXX,XX +XXX,XX @@ struct sparx5_port_qos_dscp { | 82 | @@ -XXX,XX +XXX,XX @@ struct sparx5_port_qos_dscp { |
83 | struct sparx5_port_qos { | 83 | struct sparx5_port_qos { |
84 | struct sparx5_port_qos_pcp pcp; | 84 | struct sparx5_port_qos_pcp pcp; |
85 | struct sparx5_port_qos_dscp dscp; | 85 | struct sparx5_port_qos_dscp dscp; |
86 | + u8 default_prio; | 86 | + u8 default_prio; |
87 | }; | 87 | }; |
88 | 88 | ||
89 | int sparx5_port_qos_set(struct sparx5_port *port, struct sparx5_port_qos *qos); | 89 | int sparx5_port_qos_set(struct sparx5_port *port, struct sparx5_port_qos *qos); |
90 | @@ -XXX,XX +XXX,XX @@ int sparx5_port_qos_pcp_set(const struct sparx5_port *port, | 90 | @@ -XXX,XX +XXX,XX @@ int sparx5_port_qos_pcp_set(const struct sparx5_port *port, |
91 | 91 | ||
92 | int sparx5_port_qos_dscp_set(const struct sparx5_port *port, | 92 | int sparx5_port_qos_dscp_set(const struct sparx5_port *port, |
93 | struct sparx5_port_qos_dscp *qos); | 93 | struct sparx5_port_qos_dscp *qos); |
94 | + | 94 | + |
95 | +int sparx5_port_qos_default_set(const struct sparx5_port *port, | 95 | +int sparx5_port_qos_default_set(const struct sparx5_port *port, |
96 | + const struct sparx5_port_qos *qos); | 96 | + const struct sparx5_port_qos *qos); |
97 | + | 97 | + |
98 | #endif /* __SPARX5_PORT_H__ */ | 98 | #endif /* __SPARX5_PORT_H__ */ |
99 | -- | 99 | -- |
100 | 2.34.1 | 100 | 2.34.1 | diff view generated by jsdifflib |