Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: mscc: ocelot: refactor policer work out of ocelot_setup_tc_cls_matchall

In preparation for adding port mirroring support to the ocelot driver,
the dispatching function ocelot_setup_tc_cls_matchall() must be free of
action-specific code. Move port policer creation and deletion to
separate functions.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Vladimir Oltean and committed by
Jakub Kicinski
4fa72108 2b341f75

+71 -39
+71 -39
drivers/net/ethernet/mscc/ocelot_net.c
··· 216 216 } 217 217 } 218 218 219 - static int ocelot_setup_tc_cls_matchall(struct ocelot_port_private *priv, 220 - struct tc_cls_matchall_offload *f, 221 - bool ingress) 219 + static int ocelot_setup_tc_cls_matchall_police(struct ocelot_port_private *priv, 220 + struct tc_cls_matchall_offload *f, 221 + bool ingress, 222 + struct netlink_ext_ack *extack) 222 223 { 223 - struct netlink_ext_ack *extack = f->common.extack; 224 + struct flow_action_entry *action = &f->rule->action.entries[0]; 224 225 struct ocelot *ocelot = priv->port.ocelot; 225 226 struct ocelot_policer pol = { 0 }; 226 - struct flow_action_entry *action; 227 227 int port = priv->chip_port; 228 228 int err; 229 229 ··· 231 231 NL_SET_ERR_MSG_MOD(extack, "Only ingress is supported"); 232 232 return -EOPNOTSUPP; 233 233 } 234 + 235 + if (priv->tc.police_id && priv->tc.police_id != f->cookie) { 236 + NL_SET_ERR_MSG_MOD(extack, 237 + "Only one policer per port is supported"); 238 + return -EEXIST; 239 + } 240 + 241 + err = ocelot_policer_validate(&f->rule->action, action, extack); 242 + if (err) 243 + return err; 244 + 245 + pol.rate = (u32)div_u64(action->police.rate_bytes_ps, 1000) * 8; 246 + pol.burst = action->police.burst; 247 + 248 + err = ocelot_port_policer_add(ocelot, port, &pol); 249 + if (err) { 250 + NL_SET_ERR_MSG_MOD(extack, "Could not add policer"); 251 + return err; 252 + } 253 + 254 + priv->tc.police_id = f->cookie; 255 + priv->tc.offload_cnt++; 256 + 257 + return 0; 258 + } 259 + 260 + static int ocelot_del_tc_cls_matchall_police(struct ocelot_port_private *priv, 261 + struct netlink_ext_ack *extack) 262 + { 263 + struct ocelot *ocelot = priv->port.ocelot; 264 + int port = priv->chip_port; 265 + int err; 266 + 267 + err = ocelot_port_policer_del(ocelot, port); 268 + if (err) { 269 + NL_SET_ERR_MSG_MOD(extack, 270 + "Could not delete policer"); 271 + return err; 272 + } 273 + 274 + priv->tc.police_id = 0; 275 + priv->tc.offload_cnt--; 276 + 277 + return 0; 278 + } 279 + 280 + static int ocelot_setup_tc_cls_matchall(struct ocelot_port_private *priv, 281 + struct tc_cls_matchall_offload *f, 282 + bool ingress) 283 + { 284 + struct netlink_ext_ack *extack = f->common.extack; 285 + struct flow_action_entry *action; 234 286 235 287 switch (f->command) { 236 288 case TC_CLSMATCHALL_REPLACE: ··· 300 248 301 249 action = &f->rule->action.entries[0]; 302 250 303 - if (action->id != FLOW_ACTION_POLICE) { 251 + switch (action->id) { 252 + case FLOW_ACTION_POLICE: 253 + return ocelot_setup_tc_cls_matchall_police(priv, f, 254 + ingress, 255 + extack); 256 + break; 257 + default: 304 258 NL_SET_ERR_MSG_MOD(extack, "Unsupported action"); 305 259 return -EOPNOTSUPP; 306 260 } 307 261 308 - if (priv->tc.police_id && priv->tc.police_id != f->cookie) { 309 - NL_SET_ERR_MSG_MOD(extack, 310 - "Only one policer per port is supported"); 311 - return -EEXIST; 312 - } 313 - 314 - err = ocelot_policer_validate(&f->rule->action, action, 315 - extack); 316 - if (err) 317 - return err; 318 - 319 - pol.rate = (u32)div_u64(action->police.rate_bytes_ps, 1000) * 8; 320 - pol.burst = action->police.burst; 321 - 322 - err = ocelot_port_policer_add(ocelot, port, &pol); 323 - if (err) { 324 - NL_SET_ERR_MSG_MOD(extack, "Could not add policer"); 325 - return err; 326 - } 327 - 328 - priv->tc.police_id = f->cookie; 329 - priv->tc.offload_cnt++; 330 - return 0; 262 + break; 331 263 case TC_CLSMATCHALL_DESTROY: 332 - if (priv->tc.police_id != f->cookie) 264 + action = &f->rule->action.entries[0]; 265 + 266 + if (f->cookie == priv->tc.police_id) 267 + return ocelot_del_tc_cls_matchall_police(priv, extack); 268 + else 333 269 return -ENOENT; 334 270 335 - err = ocelot_port_policer_del(ocelot, port); 336 - if (err) { 337 - NL_SET_ERR_MSG_MOD(extack, 338 - "Could not delete policer"); 339 - return err; 340 - } 341 - priv->tc.police_id = 0; 342 - priv->tc.offload_cnt--; 343 - return 0; 271 + break; 344 272 case TC_CLSMATCHALL_STATS: 345 273 default: 346 274 return -EOPNOTSUPP;