Search Linux Wireless

[PATCH] mac80211_hwsim: configfs support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Mac80211_hwsim: Support to configfs operations for create a new radio

Signed-off-by: Igor Trindade Oliveira (igor_trindade@xxxxxxxxxxxx)

--- wireless-testing/drivers/net/wireless/mac80211_hwsim.c.orig	2008-12-01 10:43:42.000000000 -0400
+++ wireless-testing/drivers/net/wireless/mac80211_hwsim.c	2008-12-02 06:21:56.000000000 -0400
@@ -21,15 +21,13 @@
 #include <linux/if_arp.h>
 #include <linux/rtnetlink.h>
 #include <linux/etherdevice.h>
-#include <linux/debugfs.h>
+#include <linux/configfs.h>
 
 MODULE_AUTHOR("Jouni Malinen");
 MODULE_DESCRIPTION("Software simulator of 802.11 radio(s) for mac80211");
 MODULE_LICENSE("GPL");
 
-static int radios = 2;
-module_param(radios, int, 0444);
-MODULE_PARM_DESC(radios, "Number of simulated radios");
+static int radios;
 
 struct hwsim_vif_priv {
 	u32 magic;
@@ -140,10 +138,15 @@ struct mac80211_hwsim_data {
 		PS_DISABLED, PS_ENABLED, PS_AUTO_POLL, PS_MANUAL_POLL
 	} ps;
 	bool ps_poll_pending;
-	struct dentry *debugfs;
-	struct dentry *debugfs_ps;
+	struct config_item item;
 };
 
+struct mac80211_hwsim_attr {
+	struct configfs_attribute attr;
+	 ssize_t(*show) (struct mac80211_hwsim_data *hwsim, char *buf);
+	 ssize_t(*store) (struct mac80211_hwsim_data *hwsim,
+			  const char *buf, ssize_t count);
+};
 
 struct hwsim_radiotap_hdr {
 	struct ieee80211_radiotap_header hdr;
@@ -576,8 +579,6 @@ static void mac80211_hwsim_free(void)
 	spin_unlock_bh(&hwsim_radio_lock);
 
 	list_for_each_entry(data, &tmplist, list) {
-		debugfs_remove(data->debugfs_ps);
-		debugfs_remove(data->debugfs);
 		ieee80211_unregister_hw(data->hw);
 		device_unregister(data->dev);
 		ieee80211_free_hw(data->hw);
@@ -683,150 +684,266 @@ static void hwsim_send_nullfunc_no_ps(vo
 	hwsim_send_nullfunc(data, mac, vif, 0);
 }
 
+/*
+ *ConfigFs operations
+ */
 
-static int hwsim_fops_ps_read(void *dat, u64 *val)
+static struct mac80211_hwsim_data *to_target(struct config_item *item)
 {
-	struct mac80211_hwsim_data *data = dat;
-	*val = data->ps;
-	return 0;
+	return item ?
+	    container_of(item, struct mac80211_hwsim_data, item) : NULL;
 }
 
-static int hwsim_fops_ps_write(void *dat, u64 val)
+static int show_ps_status(struct mac80211_hwsim_data *hwsim, char *buf)
 {
-	struct mac80211_hwsim_data *data = dat;
+	return snprintf(buf, PAGE_SIZE, "%d\n", hwsim->ps);
+}
+
+static int store_ps_status(struct mac80211_hwsim_data *hwsim,
+			   const char *buf, ssize_t count)
+{
+	unsigned long int ps;
 	enum ps_mode old_ps;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &ps);
 
-	if (val != PS_DISABLED && val != PS_ENABLED && val != PS_AUTO_POLL &&
-	    val != PS_MANUAL_POLL)
+	if (ret)
+		return ret;
+
+	if (ps != PS_DISABLED && ps != PS_ENABLED && ps != PS_AUTO_POLL &&
+	    ps != PS_MANUAL_POLL)
 		return -EINVAL;
 
-	old_ps = data->ps;
-	data->ps = val;
+	old_ps = hwsim->ps;
+	hwsim->ps = ps;
 
-	if (val == PS_MANUAL_POLL) {
-		ieee80211_iterate_active_interfaces(data->hw,
-						    hwsim_send_ps_poll, data);
-		data->ps_poll_pending = true;
-	} else if (old_ps == PS_DISABLED && val != PS_DISABLED) {
-		ieee80211_iterate_active_interfaces(data->hw,
+	if (ps == PS_MANUAL_POLL) {
+		ieee80211_iterate_active_interfaces(hwsim->hw,
+						    hwsim_send_ps_poll, hwsim);
+		hwsim->ps_poll_pending = true;
+	} else if (old_ps == PS_DISABLED && ps != PS_DISABLED) {
+		ieee80211_iterate_active_interfaces(hwsim->hw,
 						    hwsim_send_nullfunc_ps,
-						    data);
-	} else if (old_ps != PS_DISABLED && val == PS_DISABLED) {
-		ieee80211_iterate_active_interfaces(data->hw,
+						    hwsim);
+	} else if (old_ps != PS_DISABLED && ps == PS_DISABLED) {
+		ieee80211_iterate_active_interfaces(hwsim->hw,
 						    hwsim_send_nullfunc_no_ps,
-						    data);
+						    hwsim);
 	}
 
-	return 0;
+	return strnlen(buf, count);
 }
 
-DEFINE_SIMPLE_ATTRIBUTE(hwsim_fops_ps, hwsim_fops_ps_read, hwsim_fops_ps_write,
-			"%llu\n");
+/*
+ *ConfigFS attribute declaration
+ */
+#define MAC80211_HWSIM_ATTR_RW(_name, _show, _store)                    \
+static struct  mac80211_hwsim_attr mac80211_hwsim_##_name =	        \
+		 __CONFIGFS_ATTR(_name, S_IRUGO | S_IWUSR, _show, _store)
 
+MAC80211_HWSIM_ATTR_RW(ps, show_ps_status, store_ps_status);
 
-static int __init init_mac80211_hwsim(void)
+static struct configfs_atribbute *mac80211_hwsim_attrs[] = {
+	&mac80211_hwsim_ps.attr,
+	NULL,
+};
+
+/*
+ *ConfigFS: Item operations
+ */
+
+static void mac80211_hwsim_release(struct config_item *item)
+{
+	kfree(to_target(item));
+}
+
+/*
+ * now we just have one attribute with this function we can
+ * add new attributes in mac80211_hwsim_attrs and do not change
+ * others parts of the code
+ */
+
+static ssize_t mac80211_hwsim_attr_show(struct config_item *item,
+					struct configfs_attribute *attr,
+					char *buf)
 {
-	int i, err = 0;
+	struct mac80211_hwsim_data *data = to_target(item);
+	struct mac80211_hwsim_attr *hwsim_attr =
+	    container_of(attr, struct mac80211_hwsim_attr, attr);
+
+	return hwsim_attr->show ? hwsim_attr->show(data, buf) : EINVAL;
+}
+
+static ssize_t mac80211_hwsim_attr_store(struct config_item *item,
+					 struct configfs_attribute *attr,
+					 const char *buf, size_t count)
+{
+	struct mac80211_hwsim_data *data = to_target(item);
+	struct mac80211_hwsim_attr *hwsim_attr =
+	    container_of(attr, struct mac80211_hwsim_attr, attr);
+
+	return hwsim_attr->store ? hwsim_attr->store(data, buf, count) : EINVAL;
+}
+
+static struct configfs_item_operations mac80211_hwsim_item_ops = {
+	.release = mac80211_hwsim_release,
+	.show_attribute = mac80211_hwsim_attr_show,
+	.store_attribute = mac80211_hwsim_attr_store,
+};
+
+static struct config_item_type mac80211_hwsim_type = {
+	.ct_attrs = mac80211_hwsim_attrs,
+	.ct_item_ops = &mac80211_hwsim_item_ops,
+	.ct_owner = THIS_MODULE,
+};
+
+
+static struct config_item *make_mac80211_hwsim(struct config_group *group,
+					       const char *name)
+{
+	int err = 0;
 	u8 addr[ETH_ALEN];
 	struct mac80211_hwsim_data *data;
 	struct ieee80211_hw *hw;
 	DECLARE_MAC_BUF(mac);
 
-	if (radios < 1 || radios > 100)
-		return -EINVAL;
-
-	spin_lock_init(&hwsim_radio_lock);
-	INIT_LIST_HEAD(&hwsim_radios);
-
-	hwsim_class = class_create(THIS_MODULE, "mac80211_hwsim");
-	if (IS_ERR(hwsim_class))
-		return PTR_ERR(hwsim_class);
-
 	memset(addr, 0, ETH_ALEN);
 	addr[0] = 0x02;
 
-	for (i = 0; i < radios; i++) {
-		printk(KERN_DEBUG "mac80211_hwsim: Initializing radio %d\n",
-		       i);
-		hw = ieee80211_alloc_hw(sizeof(*data), &mac80211_hwsim_ops);
-		if (!hw) {
-			printk(KERN_DEBUG "mac80211_hwsim: ieee80211_alloc_hw "
-			       "failed\n");
-			err = -ENOMEM;
+	printk(KERN_DEBUG "mac80211_hwsim: Initializing radio %d\n",
+		       radios);
+	hw = ieee80211_alloc_hw(sizeof(*data), &mac80211_hwsim_ops);
+	if (!hw) {
+		printk(KERN_DEBUG "mac80211_hwsim: ieee80211_alloc_hw "
+			"failed\n");
+		err = -ENOMEM;
 			goto failed;
-		}
-		data = hw->priv;
-		data->hw = hw;
+	}
+	data = hw->priv;
+	data->hw = hw;
 
-		data->dev = device_create(hwsim_class, NULL, 0, hw,
-					  "hwsim%d", i);
-		if (IS_ERR(data->dev)) {
-			printk(KERN_DEBUG
-			       "mac80211_hwsim: device_create "
-			       "failed (%ld)\n", PTR_ERR(data->dev));
-			err = -ENOMEM;
-			goto failed_drvdata;
-		}
-		data->dev->driver = &mac80211_hwsim_driver;
+	data->dev = device_create(hwsim_class, NULL, 0, hw,
+					  "hwsim%d", radios);
+	if (IS_ERR(data->dev)) {
+		printk(KERN_DEBUG
+			"mac80211_hwsim: device_create "
+			"failed (%ld)\n", PTR_ERR(data->dev));
+		err = -ENOMEM;
+		goto failed_drvdata;
+	}
+	data->dev->driver = &mac80211_hwsim_driver;
+
+	SET_IEEE80211_DEV(hw, data->dev);
+	addr[3] = radios >> 8;
+	addr[4] = radios;
+	SET_IEEE80211_PERM_ADDR(hw, addr);
+
+	hw->channel_change_time = 1;
+	hw->queues = 4;
+	hw->wiphy->interface_modes =
+		BIT(NL80211_IFTYPE_STATION) |
+		BIT(NL80211_IFTYPE_AP) |
+		BIT(NL80211_IFTYPE_MESH_POINT);
+	hw->ampdu_queues = 1;
+
+	/* ask mac80211 to reserve space for magic */
+	hw->vif_data_size = sizeof(struct hwsim_vif_priv);
+	hw->sta_data_size = sizeof(struct hwsim_sta_priv);
+
+	memcpy(data->channels, hwsim_channels, sizeof(hwsim_channels));
+	memcpy(data->rates, hwsim_rates, sizeof(hwsim_rates));
+	data->band.channels = data->channels;
+	data->band.n_channels = ARRAY_SIZE(hwsim_channels);
+	data->band.bitrates = data->rates;
+	data->band.n_bitrates = ARRAY_SIZE(hwsim_rates);
+	data->band.ht_cap.ht_supported = true;
+	data->band.ht_cap.cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
+		IEEE80211_HT_CAP_GRN_FLD |
+		IEEE80211_HT_CAP_SGI_40 |
+		IEEE80211_HT_CAP_DSSSCCK40;
+	data->band.ht_cap.ampdu_factor = 0x3;
+	data->band.ht_cap.ampdu_density = 0x6;
+	memset(&data->band.ht_cap.mcs, 0,
+		  sizeof(data->band.ht_cap.mcs));
+	data->band.ht_cap.mcs.rx_mask[0] = 0xff;
+	data->band.ht_cap.mcs.rx_mask[1] = 0xff;
+	data->band.ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
+	hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &data->band;
+
+	err = ieee80211_register_hw(hw);
+	if (err < 0) {
+		printk(KERN_DEBUG "mac80211_hwsim: "
+		      "ieee80211_register_hw failed (%d)\n", err);
+		goto failed_hw;
+	}
+
+	printk(KERN_DEBUG "%s: hwaddr %s registered\n",
+		  wiphy_name(hw->wiphy),
+		  print_mac(mac, hw->wiphy->perm_addr));
+
+	setup_timer(&data->beacon_timer, mac80211_hwsim_beacon,
+		   (unsigned long) hw);
 
-		SET_IEEE80211_DEV(hw, data->dev);
-		addr[3] = i >> 8;
-		addr[4] = i;
-		SET_IEEE80211_PERM_ADDR(hw, addr);
-
-		hw->channel_change_time = 1;
-		hw->queues = 4;
-		hw->wiphy->interface_modes =
-			BIT(NL80211_IFTYPE_STATION) |
-			BIT(NL80211_IFTYPE_AP) |
-			BIT(NL80211_IFTYPE_MESH_POINT);
-		hw->ampdu_queues = 1;
-
-		/* ask mac80211 to reserve space for magic */
-		hw->vif_data_size = sizeof(struct hwsim_vif_priv);
-		hw->sta_data_size = sizeof(struct hwsim_sta_priv);
-
-		memcpy(data->channels, hwsim_channels, sizeof(hwsim_channels));
-		memcpy(data->rates, hwsim_rates, sizeof(hwsim_rates));
-		data->band.channels = data->channels;
-		data->band.n_channels = ARRAY_SIZE(hwsim_channels);
-		data->band.bitrates = data->rates;
-		data->band.n_bitrates = ARRAY_SIZE(hwsim_rates);
-		data->band.ht_cap.ht_supported = true;
-		data->band.ht_cap.cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
-			IEEE80211_HT_CAP_GRN_FLD |
-			IEEE80211_HT_CAP_SGI_40 |
-			IEEE80211_HT_CAP_DSSSCCK40;
-		data->band.ht_cap.ampdu_factor = 0x3;
-		data->band.ht_cap.ampdu_density = 0x6;
-		memset(&data->band.ht_cap.mcs, 0,
-		       sizeof(data->band.ht_cap.mcs));
-		data->band.ht_cap.mcs.rx_mask[0] = 0xff;
-		data->band.ht_cap.mcs.rx_mask[1] = 0xff;
-		data->band.ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
-		hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &data->band;
-
-		err = ieee80211_register_hw(hw);
-		if (err < 0) {
-			printk(KERN_DEBUG "mac80211_hwsim: "
-			       "ieee80211_register_hw failed (%d)\n", err);
-			goto failed_hw;
-		}
+	list_add_tail(&data->list, &hwsim_radios);
 
-		printk(KERN_DEBUG "%s: hwaddr %s registered\n",
-		       wiphy_name(hw->wiphy),
-		       print_mac(mac, hw->wiphy->perm_addr));
+	config_item_init_type_name(&data->item, name, &mac80211_hwsim_type);
+	radios++;
+
+	return &data->item;
+
+failed_hw:
+	device_unregister(data->dev);
+failed_drvdata:
+	ieee80211_free_hw(hw);
+failed:
+	mac80211_hwsim_free();
+	return ERR_PTR(err);
+
+}
+
+static struct configfs_group_operations mac80211_hwsim_group_ops = {
+	.make_item = make_mac80211_hwsim,
+};
+
+static struct config_item_type mac80211_hwsim_subsys_type = {
+	.ct_group_ops = &mac80211_hwsim_group_ops,
+	.ct_owner = THIS_MODULE,
+};
+
+/*
+ *Mac80211_hwsim Subsystem definition
+ */
+
+static struct configfs_subsystem mac80211_hwsim_subsys = {
+	.su_group = {
+		.cg_item = {
+			.ci_namebuf = "mac80211_hwsim",
+			.ci_type = &mac80211_hwsim_subsys_type,
+		},
+	},
+};
 
-		data->debugfs = debugfs_create_dir("hwsim",
-						   hw->wiphy->debugfsdir);
-		data->debugfs_ps = debugfs_create_file("ps", 0666,
-						       data->debugfs, data,
-						       &hwsim_fops_ps);
 
-		setup_timer(&data->beacon_timer, mac80211_hwsim_beacon,
-			    (unsigned long) hw);
+static int __init init_mac80211_hwsim(void)
+{
+	int err = 0;
+
+	spin_lock_init(&hwsim_radio_lock);
+	INIT_LIST_HEAD(&hwsim_radios);
 
-		list_add_tail(&data->list, &hwsim_radios);
+	hwsim_class = class_create(THIS_MODULE, "mac80211_hwsim");
+	if (IS_ERR(hwsim_class))
+		return PTR_ERR(hwsim_class);
+
+	config_group_init(&mac80211_hwsim_subsys.su_group);
+	mutex_init(&mac80211_hwsim_subsys.su_mutex);
+	err = configfs_register_subsystem(&mac80211_hwsim_subsys);
+	if (err) {
+		printk(KERN_ERR "Error %d while registering mac80211_hwsim_subsystem %s\n",
+			err,
+			mac80211_hwsim_subsys.su_group.cg_item.ci_namebuf);
+		goto out_unregister;
 	}
 
 	hwsim_mon = alloc_netdev(0, "hwsim%d", hwsim_mon_setup);
@@ -848,16 +965,16 @@ static int __init init_mac80211_hwsim(vo
 
 	return 0;
 
+out_unregister:
+	configfs_unregister_subsystem(&mac80211_hwsim_subsys);
+	return err;
+
 failed_mon:
 	rtnl_unlock();
 	free_netdev(hwsim_mon);
 	mac80211_hwsim_free();
 	return err;
 
-failed_hw:
-	device_unregister(data->dev);
-failed_drvdata:
-	ieee80211_free_hw(hw);
 failed:
 	mac80211_hwsim_free();
 	return err;
@@ -868,6 +985,7 @@ static void __exit exit_mac80211_hwsim(v
 {
 	printk(KERN_DEBUG "mac80211_hwsim: unregister radios\n");
 
+	configfs_unregister_subsystem(&mac80211_hwsim_subsys);
 	unregister_netdev(hwsim_mon);
 	mac80211_hwsim_free();
 }
@@ -875,3 +993,4 @@ static void __exit exit_mac80211_hwsim(v
 
 module_init(init_mac80211_hwsim);
 module_exit(exit_mac80211_hwsim);
+



      Veja quais são os assuntos do momento no Yahoo! +Buscados
http://br.maisbuscados.yahoo.com

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux