Cuttlefish Wifi: Add data ops in virt_wifi driver for scan data simulation

Bug: 139421123
Signed-off-by: lesl <lesl@google.com>
Change-Id: Ib686dffe23cc234937af7e383182834721f01d78
This commit is contained in:
lesl 2019-10-01 17:56:50 +08:00
parent ba3aa33b8f
commit e3bb9e257f
2 changed files with 69 additions and 2 deletions

View file

@ -18,6 +18,7 @@
#include <net/rtnetlink.h> #include <net/rtnetlink.h>
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
#include <linux/module.h> #include <linux/module.h>
#include <net/virt_wifi.h>
static struct wiphy *common_wiphy; static struct wiphy *common_wiphy;
@ -25,6 +26,7 @@ struct virt_wifi_wiphy_priv {
struct delayed_work scan_result; struct delayed_work scan_result;
struct cfg80211_scan_request *scan_request; struct cfg80211_scan_request *scan_request;
bool being_deleted; bool being_deleted;
struct virt_wifi_network_simulation *network_simulation;
}; };
static struct ieee80211_channel channel_2ghz = { static struct ieee80211_channel channel_2ghz = {
@ -153,6 +155,9 @@ static int virt_wifi_scan(struct wiphy *wiphy,
priv->scan_request = request; priv->scan_request = request;
schedule_delayed_work(&priv->scan_result, HZ * 2); schedule_delayed_work(&priv->scan_result, HZ * 2);
if (priv->network_simulation &&
priv->network_simulation->notify_scan_trigger)
priv->network_simulation->notify_scan_trigger(wiphy, request);
return 0; return 0;
} }
@ -183,6 +188,12 @@ static void virt_wifi_scan_result(struct work_struct *work)
DBM_TO_MBM(-50), GFP_KERNEL); DBM_TO_MBM(-50), GFP_KERNEL);
cfg80211_put_bss(wiphy, informed_bss); cfg80211_put_bss(wiphy, informed_bss);
if(priv->network_simulation &&
priv->network_simulation->generate_virt_scan_result) {
if(priv->network_simulation->generate_virt_scan_result(wiphy))
wiphy_err(wiphy, "Fail to generater the simulated scan result.\n");
}
/* Schedules work which acquires and releases the rtnl lock. */ /* Schedules work which acquires and releases the rtnl lock. */
cfg80211_scan_done(priv->scan_request, &scan_info); cfg80211_scan_done(priv->scan_request, &scan_info);
priv->scan_request = NULL; priv->scan_request = NULL;
@ -370,6 +381,8 @@ static struct wiphy *virt_wifi_make_wiphy(void)
priv = wiphy_priv(wiphy); priv = wiphy_priv(wiphy);
priv->being_deleted = false; priv->being_deleted = false;
priv->scan_request = NULL; priv->scan_request = NULL;
priv->network_simulation = NULL;
INIT_DELAYED_WORK(&priv->scan_result, virt_wifi_scan_result); INIT_DELAYED_WORK(&priv->scan_result, virt_wifi_scan_result);
err = wiphy_register(wiphy); err = wiphy_register(wiphy);
@ -385,7 +398,6 @@ static struct wiphy *virt_wifi_make_wiphy(void)
static void virt_wifi_destroy_wiphy(struct wiphy *wiphy) static void virt_wifi_destroy_wiphy(struct wiphy *wiphy)
{ {
struct virt_wifi_wiphy_priv *priv; struct virt_wifi_wiphy_priv *priv;
WARN(!wiphy, "%s called with null wiphy", __func__); WARN(!wiphy, "%s called with null wiphy", __func__);
if (!wiphy) if (!wiphy)
return; return;
@ -419,8 +431,13 @@ static netdev_tx_t virt_wifi_start_xmit(struct sk_buff *skb,
static int virt_wifi_net_device_open(struct net_device *dev) static int virt_wifi_net_device_open(struct net_device *dev)
{ {
struct virt_wifi_netdev_priv *priv = netdev_priv(dev); struct virt_wifi_netdev_priv *priv = netdev_priv(dev);
struct virt_wifi_wiphy_priv *w_priv;
priv->is_up = true; priv->is_up = true;
w_priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
if(w_priv->network_simulation &&
w_priv->network_simulation->notify_device_open)
w_priv->network_simulation->notify_device_open(dev);
return 0; return 0;
} }
@ -440,6 +457,10 @@ static int virt_wifi_net_device_stop(struct net_device *dev)
virt_wifi_cancel_connect(dev); virt_wifi_cancel_connect(dev);
netif_carrier_off(dev); netif_carrier_off(dev);
if (w_priv->network_simulation &&
w_priv->network_simulation->notify_device_stop)
w_priv->network_simulation->notify_device_stop(dev);
return 0; return 0;
} }
@ -624,6 +645,27 @@ static void __exit virt_wifi_cleanup_module(void)
virt_wifi_destroy_wiphy(common_wiphy); virt_wifi_destroy_wiphy(common_wiphy);
} }
int virt_wifi_register_network_simulation
(struct virt_wifi_network_simulation *ops)
{
struct virt_wifi_wiphy_priv *priv = wiphy_priv(common_wiphy);
if (priv->network_simulation)
return -EEXIST;
priv->network_simulation = ops;
return 0;
}
EXPORT_SYMBOL(virt_wifi_register_network_simulation);
int virt_wifi_unregister_network_simulation(void)
{
struct virt_wifi_wiphy_priv *priv = wiphy_priv(common_wiphy);
if(!priv->network_simulation)
return -ENODATA;
priv->network_simulation = NULL;
return 0;
}
EXPORT_SYMBOL(virt_wifi_unregister_network_simulation);
module_init(virt_wifi_init_module); module_init(virt_wifi_init_module);
module_exit(virt_wifi_cleanup_module); module_exit(virt_wifi_cleanup_module);

25
include/net/virt_wifi.h Normal file
View file

@ -0,0 +1,25 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* include/net/virt_wifi.h
*
* Define the extension interface for the network data simulation
*
* Copyright (C) 2019 Google, Inc.
*
* Author: lesl@google.com
*/
#ifndef __VIRT_WIFI_H
#define __VIRT_WIFI_H
struct virt_wifi_network_simulation {
void (*notify_device_open)(struct net_device *dev);
void (*notify_device_stop)(struct net_device *dev);
void (*notify_scan_trigger)(struct wiphy *wiphy,
struct cfg80211_scan_request *request);
int (*generate_virt_scan_result)(struct wiphy *wiphy);
};
int virt_wifi_register_network_simulation(
struct virt_wifi_network_simulation *ops);
int virt_wifi_unregister_network_simulation(void);
#endif