summaryrefslogtreecommitdiff
path: root/drivers/net/caif/caif_virtio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/caif/caif_virtio.c')
-rw-r--r--drivers/net/caif/caif_virtio.c99
1 files changed, 50 insertions, 49 deletions
diff --git a/drivers/net/caif/caif_virtio.c b/drivers/net/caif/caif_virtio.c
index b9ed1288ce2d..c60386bf2d1a 100644
--- a/drivers/net/caif/caif_virtio.c
+++ b/drivers/net/caif/caif_virtio.c
@@ -1,9 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) ST-Ericsson AB 2013
* Authors: Vicram Arv
* Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
* Sjur Brendeland
- * License terms: GNU General Public License (GPL) version 2
*/
#include <linux/module.h>
#include <linux/if_arp.h>
@@ -242,7 +242,7 @@ static struct sk_buff *cfv_alloc_and_copy_skb(int *err,
skb_reserve(skb, cfv->rx_hr + pad_len);
- memcpy(skb_put(skb, cfpkt_len), frm + cfv->rx_hr, cfpkt_len);
+ skb_put_data(skb, frm + cfv->rx_hr, cfpkt_len);
return skb;
}
@@ -257,7 +257,6 @@ static int cfv_rx_poll(struct napi_struct *napi, int quota)
struct vringh_kiov *riov = &cfv->ctx.riov;
unsigned int skb_len;
-again:
do {
skb = NULL;
@@ -316,13 +315,12 @@ exit:
case 0:
++cfv->stats.rx_napi_complete;
- /* Really out of patckets? (stolen from virtio_net)*/
+ /* Really out of packets? (stolen from virtio_net)*/
napi_complete(napi);
if (unlikely(!vringh_notify_enable_kern(cfv->vr_rx)) &&
napi_schedule_prep(napi)) {
vringh_notify_disable_kern(cfv->vr_rx);
__napi_schedule(napi);
- goto again;
}
break;
@@ -465,7 +463,7 @@ static int cfv_netdev_close(struct net_device *netdev)
vringh_notify_disable_kern(cfv->vr_rx);
napi_disable(&cfv->napi);
- /* Release any TX buffers on both used and avilable rings */
+ /* Release any TX buffers on both used and available rings */
cfv_release_used_buf(cfv->vq_tx);
spin_lock_irqsave(&cfv->tx_lock, flags);
while ((buf_info = virtqueue_detach_unused_buf(cfv->vq_tx)))
@@ -499,7 +497,7 @@ static struct buf_info *cfv_alloc_and_copy_to_shm(struct cfv_info *cfv,
if (unlikely(!buf_info))
goto err;
- /* Make the IP header aligned in tbe buffer */
+ /* Make the IP header aligned in the buffer */
hdr_ofs = cfv->tx_hr + info->hdr_len;
pad_len = hdr_ofs & (IP_HDR_ALIGN - 1);
buf_info->size = cfv->tx_hr + skb->len + cfv->tx_tr + pad_len;
@@ -521,7 +519,7 @@ err:
}
/* Put the CAIF packet on the virtio ring and kick the receiver */
-static int cfv_netdev_tx(struct sk_buff *skb, struct net_device *netdev)
+static netdev_tx_t cfv_netdev_tx(struct sk_buff *skb, struct net_device *netdev)
{
struct cfv_info *cfv = netdev_priv(netdev);
struct buf_info *buf_info;
@@ -600,9 +598,9 @@ err:
return NETDEV_TX_OK;
}
-static void cfv_tx_release_tasklet(unsigned long drv)
+static void cfv_tx_release_tasklet(struct tasklet_struct *t)
{
- struct cfv_info *cfv = (struct cfv_info *)drv;
+ struct cfv_info *cfv = from_tasklet(cfv, t, tx_release_tasklet);
cfv_release_used_buf(cfv->vq_tx);
}
@@ -619,49 +617,43 @@ static void cfv_netdev_setup(struct net_device *netdev)
netdev->tx_queue_len = 100;
netdev->flags = IFF_POINTOPOINT | IFF_NOARP;
netdev->mtu = CFV_DEF_MTU_SIZE;
- netdev->destructor = free_netdev;
+ netdev->needs_free_netdev = true;
}
/* Create debugfs counters for the device */
static inline void debugfs_init(struct cfv_info *cfv)
{
- cfv->debugfs =
- debugfs_create_dir(netdev_name(cfv->ndev), NULL);
+ cfv->debugfs = debugfs_create_dir(netdev_name(cfv->ndev), NULL);
- if (IS_ERR(cfv->debugfs))
- return;
-
- debugfs_create_u32("rx-napi-complete", S_IRUSR, cfv->debugfs,
+ debugfs_create_u32("rx-napi-complete", 0400, cfv->debugfs,
&cfv->stats.rx_napi_complete);
- debugfs_create_u32("rx-napi-resched", S_IRUSR, cfv->debugfs,
+ debugfs_create_u32("rx-napi-resched", 0400, cfv->debugfs,
&cfv->stats.rx_napi_resched);
- debugfs_create_u32("rx-nomem", S_IRUSR, cfv->debugfs,
+ debugfs_create_u32("rx-nomem", 0400, cfv->debugfs,
&cfv->stats.rx_nomem);
- debugfs_create_u32("rx-kicks", S_IRUSR, cfv->debugfs,
+ debugfs_create_u32("rx-kicks", 0400, cfv->debugfs,
&cfv->stats.rx_kicks);
- debugfs_create_u32("tx-full-ring", S_IRUSR, cfv->debugfs,
+ debugfs_create_u32("tx-full-ring", 0400, cfv->debugfs,
&cfv->stats.tx_full_ring);
- debugfs_create_u32("tx-no-mem", S_IRUSR, cfv->debugfs,
+ debugfs_create_u32("tx-no-mem", 0400, cfv->debugfs,
&cfv->stats.tx_no_mem);
- debugfs_create_u32("tx-kicks", S_IRUSR, cfv->debugfs,
+ debugfs_create_u32("tx-kicks", 0400, cfv->debugfs,
&cfv->stats.tx_kicks);
- debugfs_create_u32("tx-flow-on", S_IRUSR, cfv->debugfs,
+ debugfs_create_u32("tx-flow-on", 0400, cfv->debugfs,
&cfv->stats.tx_flow_on);
}
/* Setup CAIF for the a virtio device */
static int cfv_probe(struct virtio_device *vdev)
{
- vq_callback_t *vq_cbs = cfv_release_cb;
vrh_callback_t *vrh_cbs = cfv_recv;
- const char *names = "output";
const char *cfv_netdev_name = "cfvrt";
struct net_device *netdev;
struct cfv_info *cfv;
- int err = -EINVAL;
+ int err;
netdev = alloc_netdev(sizeof(struct cfv_info), cfv_netdev_name,
- cfv_netdev_setup);
+ NET_NAME_UNKNOWN, cfv_netdev_setup);
if (!netdev)
return -ENOMEM;
@@ -681,23 +673,26 @@ static int cfv_probe(struct virtio_device *vdev)
goto err;
/* Get the TX virtio ring. This is a "guest side vring". */
- err = vdev->config->find_vqs(vdev, 1, &cfv->vq_tx, &vq_cbs, &names);
- if (err)
+ cfv->vq_tx = virtio_find_single_vq(vdev, cfv_release_cb, "output");
+ if (IS_ERR(cfv->vq_tx)) {
+ err = PTR_ERR(cfv->vq_tx);
goto err;
+ }
/* Get the CAIF configuration from virtio config space, if available */
-#define GET_VIRTIO_CONFIG_OPS(_v, _var, _f) \
- ((_v)->config->get(_v, offsetof(struct virtio_caif_transf_config, _f), \
- &_var, \
- FIELD_SIZEOF(struct virtio_caif_transf_config, _f)))
-
if (vdev->config->get) {
- GET_VIRTIO_CONFIG_OPS(vdev, cfv->tx_hr, headroom);
- GET_VIRTIO_CONFIG_OPS(vdev, cfv->rx_hr, headroom);
- GET_VIRTIO_CONFIG_OPS(vdev, cfv->tx_tr, tailroom);
- GET_VIRTIO_CONFIG_OPS(vdev, cfv->rx_tr, tailroom);
- GET_VIRTIO_CONFIG_OPS(vdev, cfv->mtu, mtu);
- GET_VIRTIO_CONFIG_OPS(vdev, cfv->mru, mtu);
+ virtio_cread(vdev, struct virtio_caif_transf_config, headroom,
+ &cfv->tx_hr);
+ virtio_cread(vdev, struct virtio_caif_transf_config, headroom,
+ &cfv->rx_hr);
+ virtio_cread(vdev, struct virtio_caif_transf_config, tailroom,
+ &cfv->tx_tr);
+ virtio_cread(vdev, struct virtio_caif_transf_config, tailroom,
+ &cfv->rx_tr);
+ virtio_cread(vdev, struct virtio_caif_transf_config, mtu,
+ &cfv->mtu);
+ virtio_cread(vdev, struct virtio_caif_transf_config, mtu,
+ &cfv->mru);
} else {
cfv->tx_hr = CFV_DEF_HEADROOM;
cfv->rx_hr = CFV_DEF_HEADROOM;
@@ -719,22 +714,29 @@ static int cfv_probe(struct virtio_device *vdev)
/* Initialize NAPI poll context data */
vringh_kiov_init(&cfv->ctx.riov, NULL, 0);
cfv->ctx.head = USHRT_MAX;
- netif_napi_add(netdev, &cfv->napi, cfv_rx_poll, CFV_DEFAULT_QUOTA);
+ netif_napi_add_weight(netdev, &cfv->napi, cfv_rx_poll,
+ CFV_DEFAULT_QUOTA);
- tasklet_init(&cfv->tx_release_tasklet,
- cfv_tx_release_tasklet,
- (unsigned long)cfv);
+ tasklet_setup(&cfv->tx_release_tasklet, cfv_tx_release_tasklet);
/* Carrier is off until netdevice is opened */
netif_carrier_off(netdev);
+ /* serialize netdev register + virtio_device_ready() with ndo_open() */
+ rtnl_lock();
+
/* register Netdev */
- err = register_netdev(netdev);
+ err = register_netdevice(netdev);
if (err) {
+ rtnl_unlock();
dev_err(&vdev->dev, "Unable to register netdev (%d)\n", err);
goto err;
}
+ virtio_device_ready(vdev);
+
+ rtnl_unlock();
+
debugfs_init(cfv);
return 0;
@@ -743,7 +745,7 @@ err:
if (cfv->vr_rx)
vdev->vringh_config->del_vrhs(cfv->vdev);
- if (cfv->vdev)
+ if (cfv->vq_tx)
vdev->config->del_vqs(cfv->vdev);
free_netdev(netdev);
return err;
@@ -761,7 +763,7 @@ static void cfv_remove(struct virtio_device *vdev)
debugfs_remove_recursive(cfv->debugfs);
vringh_kiov_cleanup(&cfv->ctx.riov);
- vdev->config->reset(vdev);
+ virtio_reset_device(vdev);
vdev->vringh_config->del_vrhs(cfv->vdev);
cfv->vr_rx = NULL;
vdev->config->del_vqs(cfv->vdev);
@@ -780,7 +782,6 @@ static struct virtio_driver caif_virtio_driver = {
.feature_table = features,
.feature_table_size = ARRAY_SIZE(features),
.driver.name = KBUILD_MODNAME,
- .driver.owner = THIS_MODULE,
.id_table = id_table,
.probe = cfv_probe,
.remove = cfv_remove,