developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 1 | From 3e75ca66195dec023ca2e837ff748c317fd7ac26 Mon Sep 17 00:00:00 2001 |
| 2 | From: Sam Shih <sam.shih@mediatek.com> |
| 3 | Date: Fri, 2 Jun 2023 13:06:00 +0800 |
| 4 | Subject: [PATCH] |
| 5 | [backport-networking-drivers][999-1705-add-netlink-support-for-dsa.patch] |
| 6 | |
| 7 | --- |
| 8 | drivers/net/dsa/Makefile | 2 +- |
| 9 | drivers/net/dsa/mt7530.c | 24 ++- |
| 10 | drivers/net/dsa/mt7530.h | 8 + |
| 11 | drivers/net/dsa/mt7530_nl.c | 311 ++++++++++++++++++++++++++++++++++++ |
| 12 | drivers/net/dsa/mt7530_nl.h | 49 ++++++ |
| 13 | 5 files changed, 386 insertions(+), 8 deletions(-) |
| 14 | create mode 100644 drivers/net/dsa/mt7530_nl.c |
| 15 | create mode 100644 drivers/net/dsa/mt7530_nl.h |
| 16 | |
| 17 | diff --git a/drivers/net/dsa/Makefile b/drivers/net/dsa/Makefile |
| 18 | index 0aa10bc3d..ef563c6c1 100644 |
| 19 | --- a/drivers/net/dsa/Makefile |
| 20 | +++ b/drivers/net/dsa/Makefile |
| 21 | @@ -7,7 +7,7 @@ obj-$(CONFIG_FIXED_PHY) += dsa_loop_bdinfo.o |
developer | 2cdaeb1 | 2022-10-04 20:25:05 +0800 | [diff] [blame] | 22 | endif |
| 23 | obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o |
| 24 | obj-$(CONFIG_NET_DSA_MT7530) += mt7530-dsa.o |
| 25 | -mt7530-dsa-objs := mt7530.o mt7531_phy.o |
| 26 | +mt7530-dsa-objs := mt7530.o mt7530_nl.o mt7531_phy.o |
| 27 | obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o |
| 28 | obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o |
| 29 | obj-$(CONFIG_NET_DSA_REALTEK_SMI) += realtek-smi.o |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 30 | diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c |
| 31 | index e4c021eeb..63f8a632b 100644 |
| 32 | --- a/drivers/net/dsa/mt7530.c |
| 33 | +++ b/drivers/net/dsa/mt7530.c |
developer | 2cdaeb1 | 2022-10-04 20:25:05 +0800 | [diff] [blame] | 34 | @@ -21,6 +21,7 @@ |
| 35 | #include <net/dsa.h> |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 36 | |
developer | 2cdaeb1 | 2022-10-04 20:25:05 +0800 | [diff] [blame] | 37 | #include "mt7530.h" |
| 38 | +#include "mt7530_nl.h" |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 39 | |
developer | 2cdaeb1 | 2022-10-04 20:25:05 +0800 | [diff] [blame] | 40 | /* String, offset, and register size in bytes if different from 4 bytes */ |
| 41 | static const struct mt7530_mib_desc mt7530_mib[] = { |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 42 | @@ -222,7 +223,7 @@ mt7530_mii_read(struct mt7530_priv *priv, u32 reg) |
developer | 2cdaeb1 | 2022-10-04 20:25:05 +0800 | [diff] [blame] | 43 | return (hi << 16) | (lo & 0xffff); |
| 44 | } |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 45 | |
developer | 2cdaeb1 | 2022-10-04 20:25:05 +0800 | [diff] [blame] | 46 | -static void |
| 47 | +void |
| 48 | mt7530_write(struct mt7530_priv *priv, u32 reg, u32 val) |
| 49 | { |
| 50 | struct mii_bus *bus = priv->bus; |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 51 | @@ -255,7 +256,7 @@ _mt7530_read(struct mt7530_dummy_poll *p) |
developer | 2cdaeb1 | 2022-10-04 20:25:05 +0800 | [diff] [blame] | 52 | return val; |
| 53 | } |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 54 | |
developer | 2cdaeb1 | 2022-10-04 20:25:05 +0800 | [diff] [blame] | 55 | -static u32 |
| 56 | +u32 |
| 57 | mt7530_read(struct mt7530_priv *priv, u32 reg) |
| 58 | { |
| 59 | struct mt7530_dummy_poll p; |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 60 | @@ -614,7 +615,7 @@ static int mt7530_phy_write(struct dsa_switch *ds, int port, int regnum, |
developer | 2cdaeb1 | 2022-10-04 20:25:05 +0800 | [diff] [blame] | 61 | return mdiobus_write_nested(priv->bus, port, regnum, val); |
| 62 | } |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 63 | |
developer | 2cdaeb1 | 2022-10-04 20:25:05 +0800 | [diff] [blame] | 64 | -static int |
| 65 | +int |
| 66 | mt7531_ind_c45_phy_read(struct mt7530_priv *priv, int port, int devad, |
| 67 | int regnum) |
| 68 | { |
| 69 | @@ -663,7 +664,7 @@ out: |
| 70 | return ret; |
| 71 | } |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 72 | |
developer | 2cdaeb1 | 2022-10-04 20:25:05 +0800 | [diff] [blame] | 73 | -static int |
| 74 | +int |
| 75 | mt7531_ind_c45_phy_write(struct mt7530_priv *priv, int port, int devad, |
| 76 | int regnum, u32 data) |
| 77 | { |
| 78 | @@ -711,7 +712,7 @@ out: |
| 79 | return ret; |
| 80 | } |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 81 | |
developer | 2cdaeb1 | 2022-10-04 20:25:05 +0800 | [diff] [blame] | 82 | -static int |
| 83 | +int |
| 84 | mt7531_ind_c22_phy_read(struct mt7530_priv *priv, int port, int regnum) |
| 85 | { |
| 86 | struct mii_bus *bus = priv->bus; |
| 87 | @@ -749,7 +750,7 @@ out: |
| 88 | return ret; |
| 89 | } |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 90 | |
developer | 2cdaeb1 | 2022-10-04 20:25:05 +0800 | [diff] [blame] | 91 | -static int |
| 92 | +int |
| 93 | mt7531_ind_c22_phy_write(struct mt7530_priv *priv, int port, int regnum, |
| 94 | u16 data) |
| 95 | { |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 96 | @@ -2691,6 +2692,7 @@ mt7530_probe(struct mdio_device *mdiodev) |
developer | 2cdaeb1 | 2022-10-04 20:25:05 +0800 | [diff] [blame] | 97 | { |
| 98 | struct mt7530_priv *priv; |
| 99 | struct device_node *dn; |
| 100 | + int ret; |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 101 | |
developer | 2cdaeb1 | 2022-10-04 20:25:05 +0800 | [diff] [blame] | 102 | dn = mdiodev->dev.of_node; |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 103 | |
| 104 | @@ -2766,7 +2768,13 @@ mt7530_probe(struct mdio_device *mdiodev) |
developer | 2cdaeb1 | 2022-10-04 20:25:05 +0800 | [diff] [blame] | 105 | mutex_init(&priv->reg_mutex); |
| 106 | dev_set_drvdata(&mdiodev->dev, priv); |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 107 | |
developer | 2cdaeb1 | 2022-10-04 20:25:05 +0800 | [diff] [blame] | 108 | - return dsa_register_switch(priv->ds); |
| 109 | + ret = dsa_register_switch(priv->ds); |
| 110 | + if (ret) |
| 111 | + return ret; |
| 112 | + |
| 113 | + mt7530_nl_init(&priv); |
| 114 | + |
| 115 | + return 0; |
| 116 | } |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 117 | |
developer | 2cdaeb1 | 2022-10-04 20:25:05 +0800 | [diff] [blame] | 118 | static void |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 119 | @@ -2787,6 +2795,8 @@ mt7530_remove(struct mdio_device *mdiodev) |
| 120 | |
developer | 2cdaeb1 | 2022-10-04 20:25:05 +0800 | [diff] [blame] | 121 | dsa_unregister_switch(priv->ds); |
| 122 | mutex_destroy(&priv->reg_mutex); |
| 123 | + |
| 124 | + mt7530_nl_exit(); |
| 125 | } |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 126 | |
developer | 2cdaeb1 | 2022-10-04 20:25:05 +0800 | [diff] [blame] | 127 | static struct mdio_driver mt7530_mdio_driver = { |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 128 | diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h |
| 129 | index 8f1e827ff..130d7e5ec 100644 |
| 130 | --- a/drivers/net/dsa/mt7530.h |
| 131 | +++ b/drivers/net/dsa/mt7530.h |
| 132 | @@ -783,4 +783,12 @@ static inline void INIT_MT7530_DUMMY_POLL(struct mt7530_dummy_poll *p, |
developer | 2cdaeb1 | 2022-10-04 20:25:05 +0800 | [diff] [blame] | 133 | } |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 134 | |
developer | 2cdaeb1 | 2022-10-04 20:25:05 +0800 | [diff] [blame] | 135 | int mt7531_phy_setup(struct dsa_switch *ds); |
| 136 | +u32 mt7530_read(struct mt7530_priv *priv, u32 reg); |
| 137 | +void mt7530_write(struct mt7530_priv *priv, u32 reg, u32 val); |
| 138 | +int mt7531_ind_c45_phy_read(struct mt7530_priv *priv, int port, int devad, int regnum); |
| 139 | +int mt7531_ind_c45_phy_write(struct mt7530_priv *priv, int port, int devad, int regnum, u32 data); |
| 140 | +int mt7531_ind_c22_phy_read(struct mt7530_priv *priv, int port, int regnum); |
| 141 | +int mt7531_ind_c22_phy_write(struct mt7530_priv *priv, int port, int regnum, u16 data); |
| 142 | + |
| 143 | + |
| 144 | #endif /* __MT7530_H */ |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 145 | diff --git a/drivers/net/dsa/mt7530_nl.c b/drivers/net/dsa/mt7530_nl.c |
| 146 | new file mode 100644 |
| 147 | index 000000000..676adef70 |
developer | 2cdaeb1 | 2022-10-04 20:25:05 +0800 | [diff] [blame] | 148 | --- /dev/null |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 149 | +++ b/drivers/net/dsa/mt7530_nl.c |
developer | 2cdaeb1 | 2022-10-04 20:25:05 +0800 | [diff] [blame] | 150 | @@ -0,0 +1,311 @@ |
| 151 | +// SPDX-License-Identifier: GPL-2.0
|
| 152 | +/*
|
| 153 | + * Copyright (c) 2018 MediaTek Inc.
|
| 154 | + * Author: Sirui Zhao <Sirui.Zhao@mediatek.com>
|
| 155 | + */
|
| 156 | +
|
| 157 | +#include <linux/types.h>
|
| 158 | +#include <linux/kernel.h>
|
| 159 | +#include <linux/module.h>
|
| 160 | +#include <linux/init.h>
|
| 161 | +#include <net/genetlink.h>
|
| 162 | +#include <linux/of_mdio.h>
|
| 163 | +#include <linux/phylink.h>
|
| 164 | +#include <net/dsa.h>
|
| 165 | +
|
| 166 | +#include "mt7530.h"
|
| 167 | +#include "mt7530_nl.h"
|
| 168 | +
|
| 169 | +struct mt7530_nl_cmd_item {
|
| 170 | + enum mt7530_cmd cmd;
|
| 171 | + bool require_dev;
|
| 172 | + int (*process)(struct genl_info *info);
|
| 173 | + u32 nr_required_attrs;
|
| 174 | + const enum mt7530_attr *required_attrs;
|
| 175 | +};
|
| 176 | +
|
| 177 | +struct mt7530_priv *sw_priv;
|
| 178 | +
|
| 179 | +static DEFINE_MUTEX(mt7530_devs_lock);
|
| 180 | +
|
| 181 | +void mt7530_put(void)
|
| 182 | +{
|
| 183 | + mutex_unlock(&mt7530_devs_lock);
|
| 184 | +}
|
| 185 | +
|
| 186 | +void mt7530_lock(void)
|
| 187 | +{
|
| 188 | + mutex_lock(&mt7530_devs_lock);
|
| 189 | +}
|
| 190 | +
|
| 191 | +static int mt7530_nl_response(struct sk_buff *skb, struct genl_info *info);
|
| 192 | +
|
| 193 | +static const struct nla_policy mt7530_nl_cmd_policy[] = {
|
| 194 | + [MT7530_ATTR_TYPE_MESG] = { .type = NLA_STRING },
|
| 195 | + [MT7530_ATTR_TYPE_PHY] = { .type = NLA_S32 },
|
| 196 | + [MT7530_ATTR_TYPE_REG] = { .type = NLA_S32 },
|
| 197 | + [MT7530_ATTR_TYPE_VAL] = { .type = NLA_S32 },
|
| 198 | + [MT7530_ATTR_TYPE_DEV_NAME] = { .type = NLA_S32 },
|
| 199 | + [MT7530_ATTR_TYPE_DEV_ID] = { .type = NLA_S32 },
|
| 200 | + [MT7530_ATTR_TYPE_DEVAD] = { .type = NLA_S32 },
|
| 201 | +};
|
| 202 | +
|
| 203 | +static const struct genl_ops mt7530_nl_ops[] = {
|
| 204 | + {
|
| 205 | + .cmd = MT7530_CMD_REQUEST,
|
| 206 | + .doit = mt7530_nl_response,
|
| 207 | + .flags = GENL_ADMIN_PERM,
|
| 208 | + }, {
|
| 209 | + .cmd = MT7530_CMD_READ,
|
| 210 | + .doit = mt7530_nl_response,
|
| 211 | + .flags = GENL_ADMIN_PERM,
|
| 212 | + }, {
|
| 213 | + .cmd = MT7530_CMD_WRITE,
|
| 214 | + .doit = mt7530_nl_response,
|
| 215 | + .flags = GENL_ADMIN_PERM,
|
| 216 | + },
|
| 217 | +};
|
| 218 | +
|
| 219 | +static struct genl_family mt7530_nl_family = {
|
| 220 | + .name = MT7530_DSA_GENL_NAME,
|
| 221 | + .version = MT7530_GENL_VERSION,
|
| 222 | + .maxattr = MT7530_NR_ATTR_TYPE,
|
| 223 | + .ops = mt7530_nl_ops,
|
| 224 | + .n_ops = ARRAY_SIZE(mt7530_nl_ops),
|
| 225 | + .policy = mt7530_nl_cmd_policy,
|
| 226 | +};
|
| 227 | +
|
| 228 | +static int mt7530_nl_prepare_reply(struct genl_info *info, u8 cmd,
|
| 229 | + struct sk_buff **skbp)
|
| 230 | +{
|
| 231 | + struct sk_buff *msg;
|
| 232 | + void *reply;
|
| 233 | +
|
| 234 | + if (!info)
|
| 235 | + return -EINVAL;
|
| 236 | +
|
| 237 | + msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
|
| 238 | + if (!msg)
|
| 239 | + return -ENOMEM;
|
| 240 | +
|
| 241 | + /* Construct send-back message header */
|
| 242 | + reply = genlmsg_put(msg, info->snd_portid, info->snd_seq,
|
| 243 | + &mt7530_nl_family, 0, cmd);
|
| 244 | + if (!reply) {
|
| 245 | + nlmsg_free(msg);
|
| 246 | + return -EINVAL;
|
| 247 | + }
|
| 248 | +
|
| 249 | + *skbp = msg;
|
| 250 | + return 0;
|
| 251 | +}
|
| 252 | +
|
| 253 | +static int mt7530_nl_send_reply(struct sk_buff *skb, struct genl_info *info)
|
| 254 | +{
|
| 255 | + struct genlmsghdr *genlhdr = nlmsg_data(nlmsg_hdr(skb));
|
| 256 | + void *reply = genlmsg_data(genlhdr);
|
| 257 | +
|
| 258 | + /* Finalize a generic netlink message (update message header) */
|
| 259 | + genlmsg_end(skb, reply);
|
| 260 | +
|
| 261 | + /* reply to a request */
|
| 262 | + return genlmsg_reply(skb, info);
|
| 263 | +}
|
| 264 | +
|
| 265 | +static s32 mt7530_nl_get_s32(struct genl_info *info, enum mt7530_attr attr,
|
| 266 | + s32 defval)
|
| 267 | +{
|
| 268 | + struct nlattr *na;
|
| 269 | +
|
| 270 | + na = info->attrs[attr];
|
| 271 | + if (na)
|
| 272 | + return nla_get_s32(na);
|
| 273 | +
|
| 274 | + return defval;
|
| 275 | +}
|
| 276 | +
|
| 277 | +static int mt7530_nl_get_u32(struct genl_info *info, enum mt7530_attr attr,
|
| 278 | + u32 *val)
|
| 279 | +{
|
| 280 | + struct nlattr *na;
|
| 281 | +
|
| 282 | + na = info->attrs[attr];
|
| 283 | + if (na) {
|
| 284 | + *val = nla_get_u32(na);
|
| 285 | + return 0;
|
| 286 | + }
|
| 287 | +
|
| 288 | + return -1;
|
| 289 | +}
|
| 290 | +
|
| 291 | +static int mt7530_nl_reply_read(struct genl_info *info)
|
| 292 | +{
|
| 293 | + struct sk_buff *rep_skb = NULL;
|
| 294 | + s32 phy, devad, reg;
|
| 295 | + int value;
|
| 296 | + int ret = 0;
|
| 297 | +
|
| 298 | + phy = mt7530_nl_get_s32(info, MT7530_ATTR_TYPE_PHY, -1);
|
| 299 | + devad = mt7530_nl_get_s32(info, MT7530_ATTR_TYPE_DEVAD, -1);
|
| 300 | + reg = mt7530_nl_get_s32(info, MT7530_ATTR_TYPE_REG, -1);
|
| 301 | +
|
| 302 | + if (reg < 0)
|
| 303 | + goto err;
|
| 304 | +
|
| 305 | + ret = mt7530_nl_prepare_reply(info, MT7530_CMD_READ, &rep_skb);
|
| 306 | + if (ret < 0)
|
| 307 | + goto err;
|
| 308 | +
|
| 309 | + if (phy >= 0) {
|
| 310 | + if (devad < 0)
|
| 311 | + value = mt7531_ind_c22_phy_read(sw_priv, phy, reg);
|
| 312 | + else
|
| 313 | + value = mt7531_ind_c45_phy_read(sw_priv, phy, devad, reg);
|
| 314 | + } else
|
| 315 | + value = mt7530_read(sw_priv, reg);
|
| 316 | +
|
| 317 | + ret = nla_put_s32(rep_skb, MT7530_ATTR_TYPE_REG, reg);
|
| 318 | + if (ret < 0)
|
| 319 | + goto err;
|
| 320 | +
|
| 321 | + ret = nla_put_s32(rep_skb, MT7530_ATTR_TYPE_VAL, value);
|
| 322 | + if (ret < 0)
|
| 323 | + goto err;
|
| 324 | +
|
| 325 | + return mt7530_nl_send_reply(rep_skb, info);
|
| 326 | +
|
| 327 | +err:
|
| 328 | + if (rep_skb)
|
| 329 | + nlmsg_free(rep_skb);
|
| 330 | +
|
| 331 | + return ret;
|
| 332 | +}
|
| 333 | +
|
| 334 | +static int mt7530_nl_reply_write(struct genl_info *info)
|
| 335 | +{
|
| 336 | + struct sk_buff *rep_skb = NULL;
|
| 337 | + s32 phy, devad, reg;
|
| 338 | + u32 value;
|
| 339 | + int ret = 0;
|
| 340 | +
|
| 341 | + phy = mt7530_nl_get_s32(info, MT7530_ATTR_TYPE_PHY, -1);
|
| 342 | + devad = mt7530_nl_get_s32(info, MT7530_ATTR_TYPE_DEVAD, -1);
|
| 343 | + reg = mt7530_nl_get_s32(info, MT7530_ATTR_TYPE_REG, -1);
|
| 344 | +
|
| 345 | + if (mt7530_nl_get_u32(info, MT7530_ATTR_TYPE_VAL, &value))
|
| 346 | + goto err;
|
| 347 | +
|
| 348 | + if (reg < 0)
|
| 349 | + goto err;
|
| 350 | +
|
| 351 | + ret = mt7530_nl_prepare_reply(info, MT7530_CMD_WRITE, &rep_skb);
|
| 352 | + if (ret < 0)
|
| 353 | + goto err;
|
| 354 | +
|
| 355 | + if (phy >= 0) {
|
| 356 | + if (devad < 0)
|
| 357 | + mt7531_ind_c22_phy_write(sw_priv, phy, reg, value);
|
| 358 | + else
|
| 359 | + mt7531_ind_c45_phy_write(sw_priv, phy, devad, reg, value);
|
| 360 | + } else
|
| 361 | + mt7530_write(sw_priv, reg, value);
|
| 362 | +
|
| 363 | + ret = nla_put_s32(rep_skb, MT7530_ATTR_TYPE_REG, reg);
|
| 364 | + if (ret < 0)
|
| 365 | + goto err;
|
| 366 | +
|
| 367 | + ret = nla_put_s32(rep_skb, MT7530_ATTR_TYPE_VAL, value);
|
| 368 | + if (ret < 0)
|
| 369 | + goto err;
|
| 370 | +
|
| 371 | + return mt7530_nl_send_reply(rep_skb, info);
|
| 372 | +
|
| 373 | +err:
|
| 374 | + if (rep_skb)
|
| 375 | + nlmsg_free(rep_skb);
|
| 376 | +
|
| 377 | + return ret;
|
| 378 | +}
|
| 379 | +
|
| 380 | +static const enum mt7530_attr mt7530_nl_cmd_read_attrs[] = {
|
| 381 | + MT7530_ATTR_TYPE_REG
|
| 382 | +};
|
| 383 | +
|
| 384 | +static const enum mt7530_attr mt7530_nl_cmd_write_attrs[] = {
|
| 385 | + MT7530_ATTR_TYPE_REG,
|
| 386 | + MT7530_ATTR_TYPE_VAL
|
| 387 | +};
|
| 388 | +
|
| 389 | +static const struct mt7530_nl_cmd_item mt7530_nl_cmds[] = {
|
| 390 | + {
|
| 391 | + .cmd = MT7530_CMD_READ,
|
| 392 | + .require_dev = true,
|
| 393 | + .process = mt7530_nl_reply_read,
|
| 394 | + .required_attrs = mt7530_nl_cmd_read_attrs,
|
| 395 | + .nr_required_attrs = ARRAY_SIZE(mt7530_nl_cmd_read_attrs),
|
| 396 | + }, {
|
| 397 | + .cmd = MT7530_CMD_WRITE,
|
| 398 | + .require_dev = true,
|
| 399 | + .process = mt7530_nl_reply_write,
|
| 400 | + .required_attrs = mt7530_nl_cmd_write_attrs,
|
| 401 | + .nr_required_attrs = ARRAY_SIZE(mt7530_nl_cmd_write_attrs),
|
| 402 | + }
|
| 403 | +};
|
| 404 | +
|
| 405 | +static int mt7530_nl_response(struct sk_buff *skb, struct genl_info *info)
|
| 406 | +{
|
| 407 | + struct genlmsghdr *hdr = nlmsg_data(info->nlhdr);
|
| 408 | + const struct mt7530_nl_cmd_item *cmditem = NULL;
|
| 409 | + u32 sat_req_attrs = 0;
|
| 410 | + int i, ret;
|
| 411 | +
|
| 412 | + for (i = 0; i < ARRAY_SIZE(mt7530_nl_cmds); i++) {
|
| 413 | + if (hdr->cmd == mt7530_nl_cmds[i].cmd) {
|
| 414 | + cmditem = &mt7530_nl_cmds[i];
|
| 415 | + break;
|
| 416 | + }
|
| 417 | + }
|
| 418 | +
|
| 419 | + if (!cmditem) {
|
| 420 | + pr_info("mt7530-nl: unknown cmd %u\n", hdr->cmd);
|
| 421 | + return -EINVAL;
|
| 422 | + }
|
| 423 | +
|
| 424 | + for (i = 0; i < cmditem->nr_required_attrs; i++) {
|
| 425 | + if (info->attrs[cmditem->required_attrs[i]])
|
| 426 | + sat_req_attrs++;
|
| 427 | + }
|
| 428 | +
|
| 429 | + if (sat_req_attrs != cmditem->nr_required_attrs) {
|
| 430 | + pr_info("mt7530-nl: missing required attr(s) for cmd %u\n",
|
| 431 | + hdr->cmd);
|
| 432 | + return -EINVAL;
|
| 433 | + }
|
| 434 | +
|
| 435 | + ret = cmditem->process(info);
|
| 436 | +
|
| 437 | + mt7530_put();
|
| 438 | +
|
| 439 | + return ret;
|
| 440 | +}
|
| 441 | +
|
| 442 | +int mt7530_nl_init(struct mt7530_priv **priv)
|
| 443 | +{
|
| 444 | + int ret;
|
| 445 | +
|
| 446 | + pr_info("mt7530-nl: genl_register_family_with_ops \n");
|
| 447 | +
|
| 448 | + sw_priv = *priv;
|
| 449 | + ret = genl_register_family(&mt7530_nl_family);
|
| 450 | + if (ret) {
|
| 451 | + return ret;
|
| 452 | + }
|
| 453 | +
|
| 454 | + return 0;
|
| 455 | +}
|
| 456 | +
|
| 457 | +void mt7530_nl_exit()
|
| 458 | +{
|
| 459 | + sw_priv = NULL;
|
| 460 | + genl_unregister_family(&mt7530_nl_family);
|
| 461 | +}
|
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 462 | diff --git a/drivers/net/dsa/mt7530_nl.h b/drivers/net/dsa/mt7530_nl.h |
| 463 | new file mode 100644 |
| 464 | index 000000000..4619288c2 |
developer | 2cdaeb1 | 2022-10-04 20:25:05 +0800 | [diff] [blame] | 465 | --- /dev/null |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 466 | +++ b/drivers/net/dsa/mt7530_nl.h |
developer | 2cdaeb1 | 2022-10-04 20:25:05 +0800 | [diff] [blame] | 467 | @@ -0,0 +1,49 @@ |
| 468 | +/* SPDX-License-Identifier: GPL-2.0-only */
|
| 469 | +/*
|
| 470 | + * Copyright (c) 2018 MediaTek Inc.
|
| 471 | + * Author: Sirui Zhao <Sirui.Zhao@mediatek.com>
|
| 472 | + */
|
| 473 | +
|
| 474 | +#ifndef _MT753x_NL_H_
|
| 475 | +#define _MT753x_NL_H_
|
| 476 | +
|
| 477 | +#define MT7530_DSA_GENL_NAME "mt753x_dsa"
|
| 478 | +#define MT7530_GENL_VERSION 0x1
|
| 479 | +
|
| 480 | +enum mt7530_cmd {
|
| 481 | + MT7530_CMD_UNSPEC = 0,
|
| 482 | + MT7530_CMD_REQUEST,
|
| 483 | + MT7530_CMD_REPLY,
|
| 484 | + MT7530_CMD_READ,
|
| 485 | + MT7530_CMD_WRITE,
|
| 486 | +
|
| 487 | + __MT7530_CMD_MAX,
|
| 488 | +};
|
| 489 | +
|
| 490 | +enum mt7530_attr {
|
| 491 | + MT7530_ATTR_TYPE_UNSPEC = 0,
|
| 492 | + MT7530_ATTR_TYPE_MESG,
|
| 493 | + MT7530_ATTR_TYPE_PHY,
|
| 494 | + MT7530_ATTR_TYPE_DEVAD,
|
| 495 | + MT7530_ATTR_TYPE_REG,
|
| 496 | + MT7530_ATTR_TYPE_VAL,
|
| 497 | + MT7530_ATTR_TYPE_DEV_NAME,
|
| 498 | + MT7530_ATTR_TYPE_DEV_ID,
|
| 499 | +
|
| 500 | + __MT7530_ATTR_TYPE_MAX,
|
| 501 | +};
|
| 502 | +
|
| 503 | +#define MT7530_NR_ATTR_TYPE (__MT7530_ATTR_TYPE_MAX - 1)
|
| 504 | +
|
| 505 | +struct mt7530_info {
|
| 506 | + struct mii_bus *bus;
|
| 507 | + void __iomem *base;
|
| 508 | + int direct_access;
|
| 509 | +};
|
| 510 | +
|
| 511 | +#ifdef __KERNEL__
|
| 512 | +int mt7530_nl_init(struct mt7530_priv **priv);
|
| 513 | +void mt7530_nl_exit(void);
|
| 514 | +#endif /* __KERNEL__ */
|
| 515 | +
|
| 516 | +#endif /* _MT7530_NL_H_ */
|
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 517 | -- |
| 518 | 2.34.1 |
| 519 | |