summaryrefslogtreecommitdiff
path: root/drivers/net/wwan
diff options
context:
space:
mode:
authorSergey Ryazanov <ryazanov.s.a@gmail.com>2021-06-22 01:51:00 +0300
committerDavid S. Miller <davem@davemloft.net>2021-06-22 10:01:17 -0700
commit699409240389c2994e5fa1cb7d7599129bc7cfdf (patch)
treeccb93be7cb9825b86d0156507a0827cbd875fcc5 /drivers/net/wwan
parent83068395bbfcd96db74af75c6dc3a87a4f952220 (diff)
wwan: core: add WWAN common private data for netdev
The WWAN core not only multiplex the netdev configuration data, but process it too, and needs some space to store its private data associated with the netdev. Add a structure to keep common WWAN core data. The structure will be stored inside the netdev private data before WWAN driver private data and have a field to make it easier to access the driver data. Also add a helper function that simplifies drivers access to their data. At the moment we use the common WWAN private data to store the WWAN data link (channel) id at the time the link is created, and report it back to user using the .fill_info() RTNL callback. This should help the user to be aware which network interface is bound to which WWAN device data channel. Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com> CC: M Chetan Kumar <m.chetan.kumar@intel.com> CC: Intel Corporation <linuxwwan@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/wwan')
-rw-r--r--drivers/net/wwan/iosm/iosm_ipc_wwan.c12
-rw-r--r--drivers/net/wwan/wwan_core.c29
2 files changed, 34 insertions, 7 deletions
diff --git a/drivers/net/wwan/iosm/iosm_ipc_wwan.c b/drivers/net/wwan/iosm/iosm_ipc_wwan.c
index d3cb28107836..c999c64001f4 100644
--- a/drivers/net/wwan/iosm/iosm_ipc_wwan.c
+++ b/drivers/net/wwan/iosm/iosm_ipc_wwan.c
@@ -20,7 +20,7 @@
#define IOSM_IF_ID_PAYLOAD 2
/**
- * struct iosm_netdev_priv - netdev private data
+ * struct iosm_netdev_priv - netdev WWAN driver specific private data
* @ipc_wwan: Pointer to iosm_wwan struct
* @netdev: Pointer to network interface device structure
* @if_id: Interface id for device.
@@ -51,7 +51,7 @@ struct iosm_wwan {
/* Bring-up the wwan net link */
static int ipc_wwan_link_open(struct net_device *netdev)
{
- struct iosm_netdev_priv *priv = netdev_priv(netdev);
+ struct iosm_netdev_priv *priv = wwan_netdev_drvpriv(netdev);
struct iosm_wwan *ipc_wwan = priv->ipc_wwan;
int if_id = priv->if_id;
int ret;
@@ -88,7 +88,7 @@ out:
/* Bring-down the wwan net link */
static int ipc_wwan_link_stop(struct net_device *netdev)
{
- struct iosm_netdev_priv *priv = netdev_priv(netdev);
+ struct iosm_netdev_priv *priv = wwan_netdev_drvpriv(netdev);
netif_stop_queue(netdev);
@@ -105,7 +105,7 @@ static int ipc_wwan_link_stop(struct net_device *netdev)
static int ipc_wwan_link_transmit(struct sk_buff *skb,
struct net_device *netdev)
{
- struct iosm_netdev_priv *priv = netdev_priv(netdev);
+ struct iosm_netdev_priv *priv = wwan_netdev_drvpriv(netdev);
struct iosm_wwan *ipc_wwan = priv->ipc_wwan;
int if_id = priv->if_id;
int ret;
@@ -178,7 +178,7 @@ static int ipc_wwan_newlink(void *ctxt, struct net_device *dev,
if_id >= ARRAY_SIZE(ipc_wwan->sub_netlist))
return -EINVAL;
- priv = netdev_priv(dev);
+ priv = wwan_netdev_drvpriv(dev);
priv->if_id = if_id;
priv->netdev = dev;
priv->ipc_wwan = ipc_wwan;
@@ -208,8 +208,8 @@ out_unlock:
static void ipc_wwan_dellink(void *ctxt, struct net_device *dev,
struct list_head *head)
{
+ struct iosm_netdev_priv *priv = wwan_netdev_drvpriv(dev);
struct iosm_wwan *ipc_wwan = ctxt;
- struct iosm_netdev_priv *priv = netdev_priv(dev);
int if_id = priv->if_id;
if (WARN_ON(if_id < IP_MUX_SESSION_START ||
diff --git a/drivers/net/wwan/wwan_core.c b/drivers/net/wwan/wwan_core.c
index ef6ec641d877..3e16c318e705 100644
--- a/drivers/net/wwan/wwan_core.c
+++ b/drivers/net/wwan/wwan_core.c
@@ -815,6 +815,7 @@ static struct net_device *wwan_rtnl_alloc(struct nlattr *tb[],
const char *devname = nla_data(tb[IFLA_PARENT_DEV_NAME]);
struct wwan_device *wwandev = wwan_dev_get_by_name(devname);
struct net_device *dev;
+ unsigned int priv_size;
if (IS_ERR(wwandev))
return ERR_CAST(wwandev);
@@ -825,7 +826,8 @@ static struct net_device *wwan_rtnl_alloc(struct nlattr *tb[],
goto out;
}
- dev = alloc_netdev_mqs(wwandev->ops->priv_size, ifname, name_assign_type,
+ priv_size = sizeof(struct wwan_netdev_priv) + wwandev->ops->priv_size;
+ dev = alloc_netdev_mqs(priv_size, ifname, name_assign_type,
wwandev->ops->setup, num_tx_queues, num_rx_queues);
if (dev) {
@@ -845,6 +847,7 @@ static int wwan_rtnl_newlink(struct net *src_net, struct net_device *dev,
{
struct wwan_device *wwandev = wwan_dev_get_by_parent(dev->dev.parent);
u32 link_id = nla_get_u32(data[IFLA_WWAN_LINK_ID]);
+ struct wwan_netdev_priv *priv = netdev_priv(dev);
int ret;
if (IS_ERR(wwandev))
@@ -856,6 +859,7 @@ static int wwan_rtnl_newlink(struct net *src_net, struct net_device *dev,
goto out;
}
+ priv->link_id = link_id;
if (wwandev->ops->newlink)
ret = wwandev->ops->newlink(wwandev->ops_ctxt, dev,
link_id, extack);
@@ -889,6 +893,27 @@ out:
put_device(&wwandev->dev);
}
+static size_t wwan_rtnl_get_size(const struct net_device *dev)
+{
+ return
+ nla_total_size(4) + /* IFLA_WWAN_LINK_ID */
+ 0;
+}
+
+static int wwan_rtnl_fill_info(struct sk_buff *skb,
+ const struct net_device *dev)
+{
+ struct wwan_netdev_priv *priv = netdev_priv(dev);
+
+ if (nla_put_u32(skb, IFLA_WWAN_LINK_ID, priv->link_id))
+ goto nla_put_failure;
+
+ return 0;
+
+nla_put_failure:
+ return -EMSGSIZE;
+}
+
static const struct nla_policy wwan_rtnl_policy[IFLA_WWAN_MAX + 1] = {
[IFLA_WWAN_LINK_ID] = { .type = NLA_U32 },
};
@@ -900,6 +925,8 @@ static struct rtnl_link_ops wwan_rtnl_link_ops __read_mostly = {
.validate = wwan_rtnl_validate,
.newlink = wwan_rtnl_newlink,
.dellink = wwan_rtnl_dellink,
+ .get_size = wwan_rtnl_get_size,
+ .fill_info = wwan_rtnl_fill_info,
.policy = wwan_rtnl_policy,
};