net: Add DEVTYPE support for Ethernet based devices
authorMarcel Holtmann <marcel@holtmann.org>
Mon, 31 Aug 2009 21:08:19 +0000 (21:08 +0000)
committerDavid S. Miller <davem@davemloft.net>
Fri, 11 Sep 2009 19:54:55 +0000 (12:54 -0700)
The Ethernet framing is used for a lot of devices these days. Most
prominent are WiFi and WiMAX based devices. However for userspace
application it is important to classify these devices correctly and
not only see them as Ethernet devices. The daemons like HAL, DeviceKit
or even NetworkManager with udev support tries to do the classification
in userspace with a lot trickery and extra system calls. This is not
good and actually reaches its limitations. Especially since the kernel
does know the type of the Ethernet device it is pretty stupid.

To solve this problem the underlying device type needs to be set and
then the value will be exported as DEVTYPE via uevents and available
within udev.

  # cat /sys/class/net/wlan0/uevent
  DEVTYPE=wlan
  INTERFACE=wlan0
  IFINDEX=5

This is similar to subsystems like USB and SCSI that distinguish
between hosts, devices, disks, partitions etc.

The new SET_NETDEV_DEVTYPE() is a convenience helper to set the actual
device type. All device types are free form, but for convenience the
same strings as used with RFKILL are choosen.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/usb/hso.c
drivers/net/wimax/i2400m/sdio.c
drivers/net/wimax/i2400m/usb.c
include/linux/netdevice.h
net/bluetooth/bnep/core.c
net/bridge/br_if.c
net/mac80211/iface.c

index 3f9c92a2afcbddf91e4d7e47746106872fdba9e1..fa4e58196c214f3eeea5afb5893625eed58e61ce 100644 (file)
@@ -2535,6 +2535,10 @@ static void hso_create_rfkill(struct hso_device *hso_dev,
        }
 }
 
+static struct device_type hso_type = {
+       .name   = "wwan",
+};
+
 /* Creates our network device */
 static struct hso_device *hso_create_net_device(struct usb_interface *interface,
                                                int port_spec)
@@ -2575,6 +2579,7 @@ static struct hso_device *hso_create_net_device(struct usb_interface *interface,
                goto exit;
        }
        SET_NETDEV_DEV(net, &interface->dev);
+       SET_NETDEV_DEVTYPE(net, &hso_type);
 
        /* registering our net device */
        result = register_netdev(net);
index ea7b29034aab9fd308a46129f87ca65d9596b934..2981e211e04f2b77dd40a6b0bccf0186d7fcab81 100644 (file)
@@ -371,6 +371,10 @@ error:
 }
 
 
+static struct device_type i2400ms_type = {
+       .name   = "wimax",
+};
+
 /*
  * Probe a i2400m interface and register it
  *
@@ -412,6 +416,7 @@ int i2400ms_probe(struct sdio_func *func,
                goto error_alloc_netdev;
        }
        SET_NETDEV_DEV(net_dev, dev);
+       SET_NETDEV_DEVTYPE(net_dev, &i2400ms_type);
        i2400m = net_dev_to_i2400m(net_dev);
        i2400ms = container_of(i2400m, struct i2400ms, i2400m);
        i2400m->wimax_dev.net_dev = net_dev;
index cfdaf69da9d1bbc2ed98ca99848d77228c53f52e..7eadd11c815b39c4caeaf74a34757b57466bb44e 100644 (file)
@@ -351,6 +351,10 @@ error:
 }
 
 
+static struct device_type i2400mu_type = {
+       .name   = "wimax",
+};
+
 /*
  * Probe a i2400m interface and register it
  *
@@ -388,6 +392,7 @@ int i2400mu_probe(struct usb_interface *iface,
                goto error_alloc_netdev;
        }
        SET_NETDEV_DEV(net_dev, dev);
+       SET_NETDEV_DEVTYPE(net_dev, &i2400mu_type);
        i2400m = net_dev_to_i2400m(net_dev);
        i2400mu = container_of(i2400m, struct i2400mu, i2400m);
        i2400m->wimax_dev.net_dev = net_dev;
index a44118b1b56c047d1d3aed406a7e4315448f7849..65ee1929b2b1672a7cef0ca6b81af3ecca89a8bb 100644 (file)
@@ -998,6 +998,12 @@ static inline void *netdev_priv(const struct net_device *dev)
  */
 #define SET_NETDEV_DEV(net, pdev)      ((net)->dev.parent = (pdev))
 
+/* Set the sysfs device type for the network logical device to allow
+ * fin grained indentification of different network device types. For
+ * example Ethernet, Wirelss LAN, Bluetooth, WiMAX etc.
+ */
+#define SET_NETDEV_DEVTYPE(net, devtype)       ((net)->dev.type = (devtype))
+
 /**
  *     netif_napi_add - initialize a napi context
  *     @dev:  network device
index 52a6ce0d772b1f8b7e9dca07fe5c507b4e68a278..cafe9f54d8413dc181315f4d7d4792144bfe4417 100644 (file)
@@ -533,6 +533,10 @@ static struct device *bnep_get_device(struct bnep_session *session)
        return conn ? &conn->dev : NULL;
 }
 
+static struct device_type bnep_type = {
+       .name   = "bluetooth",
+};
+
 int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
 {
        struct net_device *dev;
@@ -586,6 +590,7 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
 #endif
 
        SET_NETDEV_DEV(dev, bnep_get_device(s));
+       SET_NETDEV_DEVTYPE(dev, &bnep_type);
 
        err = register_netdev(dev);
        if (err) {
index e486f1fc36324e74868d348eb9e09af2d6419fac..142ebac141764b5deffdbde15c3c6510d6e4d770 100644 (file)
@@ -264,6 +264,10 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br,
        return p;
 }
 
+static struct device_type br_type = {
+       .name   = "bridge",
+};
+
 int br_add_bridge(struct net *net, const char *name)
 {
        struct net_device *dev;
@@ -280,6 +284,8 @@ int br_add_bridge(struct net *net, const char *name)
                        goto out_free;
        }
 
+       SET_NETDEV_DEVTYPE(dev, &br_type);
+
        ret = register_netdevice(dev);
        if (ret)
                goto out_free;
index f6005adcbf90e794a5a3a5b5518aa375553eedd3..b8295cbd7e8f2243e044a611d02efd08cd5c0238 100644 (file)
@@ -754,6 +754,10 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
        return 0;
 }
 
+static struct device_type wiphy_type = {
+       .name   = "wlan",
+};
+
 int ieee80211_if_add(struct ieee80211_local *local, const char *name,
                     struct net_device **new_dev, enum nl80211_iftype type,
                     struct vif_params *params)
@@ -785,6 +789,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
 
        memcpy(ndev->dev_addr, local->hw.wiphy->perm_addr, ETH_ALEN);
        SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy));
+       SET_NETDEV_DEVTYPE(ndev, &wiphy_type);
 
        /* don't use IEEE80211_DEV_TO_SUB_IF because it checks too much */
        sdata = netdev_priv(ndev);