[802.11] Tweaks to API for clarity and practicality
authorJoshua Oreman <oremanj@xenon.get-linux.org>
Tue, 2 Jun 2009 03:45:34 +0000 (20:45 -0700)
committerJoshua Oreman <oremanj@xenon.get-linux.org>
Tue, 2 Jun 2009 03:45:34 +0000 (20:45 -0700)
In working on the rtl8185 driver, I found some issues with the
generic 802.11 API as I had originally designed it, and modified
the API headers slightly to ameliorate or clarify.

src/include/gpxe/ieee80211.h
src/include/gpxe/net80211.h

index 7a3ca6d..0e6a0eb 100644 (file)
 
 FILE_LICENCE(GPL2_OR_LATER);
 
+/* Maximum lengths of things: */
+#define IEEE80211_MAX_DATA_LEN          2304 /* plus any crypto overhead */
+#define IEEE80211_MAX_FRAME_LEN         2352
+#define IEEE80211_MAX_SSID_LEN          32
+
 /* Flags for Frame Control field, ieee80211_frame.fc: */
 #define IEEE80211_FC_VERSION   0x0003
 #define IEEE80211_FC_TYPE      0x000C
@@ -97,7 +102,8 @@ struct ieee80211_cts
 #define IEEE80211_CAPAB_QOS           0x0200 /* [0] QoS supported */
 #define IEEE80211_CAPAB_SHORT_SLOT    0x0400 /* [h] Short Slot Time option supported */
 #define IEEE80211_CAPAB_APSD          0x0800 /* [0] APSD option supported */
-#define IEEE80211_CAPAB_DSSS_OFDM     0x2000 /* [h] DSSS/OFDM modulation supported */
+#define IEEE80211_CAPAB_DSSS_OFDM     0x2000 /* [h] DSSS/OFDM modulation supported
+                                                   (802.11g/b interoperability) */
 #define IEEE80211_CAPAB_DELAYED_BACK  0x4000 /* [0] Delayed block ACK supported */
 #define IEEE80211_CAPAB_IMMED_BACK    0x8000 /* [0] Immediate block ACK supported */
 
index 4b69b17..673157e 100644 (file)
@@ -8,6 +8,25 @@
  * The gPXE 802.11 MAC layer.
  */
 
+/*
+ * Major things NOT YET supported:
+ * - any type of security (WEP, WPA, WPA2, WPA Enterprise)
+ * - adaptive rate setting
+ * - 802.11n
+ *
+ * Major things that probably will NEVER be supported, barring a
+ * compelling use case and/or corporate sponsorship: 
+ * - QoS
+ * - Contention-free periods
+ * - "ad-hoc" networks (IBSS), monitor mode, host AP mode
+ * - hidden networks on the 5GHz band due to regulatory issues
+ * - spectrum management on the 5GHz band (TPC and DFS), as required
+ *   in some non-US regulatory domains
+ * - Clause 14 PHYs (Frequency-Hopping Spread Spectrum on 2.4GHz)
+ *   and Clause 16 PHYs (infrared) - I'm not aware of any real-world
+ *   use of these.
+ */
+
 FILE_LICENCE(GPL2_OR_LATER);
 
 /* All 802.11 devices are handled using a generic "802.11 device"
@@ -15,30 +34,30 @@ FILE_LICENCE(GPL2_OR_LATER);
    which we use to handle 802.11-specific details. */
 
 /* Constants for the (*config)() callback */
-#define NET80211_CFG_CHANNEL     (1 << 0)
+#define NET80211_CFG_CHANNEL     (1 << 0) /* channel # or txpower */
 #define NET80211_CFG_RATE        (1 << 1)
 #define NET80211_CFG_ASSOC       (1 << 2)
 #define NET80211_CFG_ERP_PARAMS  (1 << 3)
-#define NET80211_CFG_BASIC_RATES (1 << 4)
 
 struct net80211_device;
 
 /** Operations that must be implemented by an 802.11 driver. */
 struct net80211_device_operations {
        /* These have the same semantics as they do in net_device. */
-       int (*open)(struct net80211_device *netdev);
-       void (*close)(struct net80211_device *netdev);
-       int (*transmit)(struct net80211_device *netdev, struct io_buffer *iobuf);
-       void (*poll)(struct net80211_device *netdev);
-       void (*irq)(struct net80211_device *netdev, int enable);
+
+       int (*open)(struct net80211_device *dev);
+       void (*close)(struct net80211_device *dev);
+       int (*transmit)(struct net80211_device *dev, struct io_buffer *iobuf);
+       void (*poll)(struct net80211_device *dev);
+       void (*irq)(struct net80211_device *dev, int enable);
 
        /* And these are specific to 802.11. */
 
        /** Update hardware state to match the state in
-           net80211_device with respect to `what', a bitwise OR of
+           net80211_device with respect to `changed', a bitwise OR of
            NET80211_CFG_* indicating what's changed. Only called when
            the device is open. */
-       int (*config)(struct net80211_device *netdev, int what);
+       int (*config)(struct net80211_device *dev, int changed);
 };
 
 #define NET80211_BAND_2GHZ  (1 << 0)   /* the 2.4 GHz ISM band */
@@ -53,7 +72,8 @@ struct net80211_channel
                                   e.g. 1-11 for the 2.4GHz band */
 
        unsigned center_freq;   /* MHz of channel center */
-       unsigned txpower;       /* maximum allowable EIRP in dBm */
+       unsigned maxpower;      /* maximum allowable EIRP in dBm */
+       unsigned txpower;       /* current requested txpower, dBm */
 
        /* There are more regulatory issues than this - bandwidth and
           antenna gain are the main ones - but we can't do anything
@@ -66,10 +86,15 @@ struct net80211_channel
 #define NET80211_MODE_G  (1 << 2)
 #define NET80211_MODE_N  (1 << 3)
 
+#define NET80211_MAX_RATES 16
+
 /** Information on the capabilities of the hardware supported by a
     driver; must be filled in by said driver. */
 struct net80211_hw_info
 {
+       /** Hardware MAC address. */
+       u8 hwaddr[ETH_ALEN];
+
        /** A bitwise OR of the 802.11x modes supported by this device. */
        int modes;              /* e.g. NET80211_MODE_B | NET80211_MODE_G */
 
@@ -77,29 +102,37 @@ struct net80211_hw_info
        int bands;              /* e.g. NET80211_BAND_2GHZ */
 
        enum {
-               /** Received frames include a frame check sequence we
-                   need to verify ourselves. */
+               /** Received frames include a frame check sequence. */
                NET80211_HW_RX_HAS_FCS = (1 << 1),
 
+               /** We need to verify the received frame check sequence. */
+               NET80211_HW_RX_UNCHECKED_FCS = (1 << 2),
+
                /** Hardware doesn't support short preambles on the
-                   2.4GHz band (802.11b). */
-               NET80211_HW_NO_SHORT_PREAMBLE = (1 << 2),
+                   2.4GHz band (all 802.11g devices do). */
+               NET80211_HW_NO_SHORT_PREAMBLE = (1 << 3),
 
                /** Hardware doesn't support short slot operation on
-                   the 2.4GHz band (802.11g). */
-               NET80211_HW_NO_SHORT_SLOT = (1 << 3),
+                   the 2.4GHz band (only relevant for 802.11g). */
+               NET80211_HW_NO_SHORT_SLOT = (1 << 4),
        } flags;
 
        /** Set according to the type of signal strength information
            that can be provided. */
        enum {
-               NET80211_SIGNAL_NONE = 0,
-               NET80211_SIGNAL_ARBITRARY, /* arbitrary units */
-               NET80211_SIGNAL_DB,        /* dB relative to arbitrary base */
-               NET80211_SIGNAL_DBM,       /* dB relative to 1mW */
-               NET80211_SIGNAL_NOISE_DBM, /* both signal and noise in dBm */
+               NET80211_SIGNAL_NONE = 0,  /**< no info at all */
+               NET80211_SIGNAL_ARBITRARY, /**< arbitrary units */
+               NET80211_SIGNAL_DB,        /**< dB relative to arbitrary base */
+               NET80211_SIGNAL_DBM,       /**< dB relative to 1mW */
+               NET80211_SIGNAL_NOISE_DBM, /**< both signal and noise in dBm */
        } signal_type;
        
+       /** List of transmit supported by the card, in 100kbps
+           increments. */
+       u16 supported_rates[NET80211_MAX_RATES];
+       /** Number of supported rates. */
+       int nr_supported_rates;
+
        /** If signal_type involves arbitrary units, it should be
            reported on a scale from 0 to signal_max. */
        unsigned signal_max;
@@ -107,10 +140,6 @@ struct net80211_hw_info
        /** Amount of time required to change channels, in
            microseconds. */
        unsigned channel_change_time;
-
-       /** Minimum and maximum power values the hardware is capable
-           of transmitting, in dBm. Set < 0 if we don't know. */
-       int txpower_min, txpower_max;
 };
 
 /** Milliseconds we'll wait to get all fragments of a packet. If this
@@ -139,8 +168,6 @@ struct net80211_frag_cache
        struct io_buffer *iob[16];
 };
 
-#define NET80211_MAX_RATES 16
-
 /** Structure encapsulating the complete state of an 802.11
     device. Stored in the `priv' member of some net_device. */
 struct net80211_device
@@ -183,7 +210,7 @@ struct net80211_device
        /** Network to which we're associated, if `assoc' is set. */
        u8 bssid[ETH_ALEN];
        /** Name of the SSID we're connected to. */
-       char essid[32];
+       char essid[IEEE80211_MAX_SSID_LEN];
        /** Association ID given to us by the AP. */
        u16 aid;
        /** ERP-related options, set dynamically based on the assoc
@@ -209,11 +236,11 @@ struct net80211_device
        int last_seqnr;
        int last_frag;
 
-       /** TX packet queue. */
+       /** TX packet queue. Packets here go onto the air. */
        struct list_head tx_queue;
 
        /** RX packet queue. Packets here go into netdev_rx(),
-           mgmt_queue, or the aether. */
+           mgmt_queue, or get dropped. */
        struct list_head rx_queue;
 
        /** Sometimes we want to keep management packets we receive,
@@ -236,7 +263,7 @@ struct net80211_device
 struct net80211_wlan
 {
        /** The human-readable ESSID (network name). */
-       char essid[32];
+       char essid[IEEE80211_MAX_SSID_LEN];
 
        /** The MAC address of the "best" access point (strongest
            signal) for this ESSID. */
@@ -261,7 +288,7 @@ struct net80211_wlan
 /* Regulatory hints when we don't get any beacons: */
 #define NET80211_REG_TXPOWER  20 /* conservative default, OK with
                                    US/EU/JP at least */
-/* 2.4GHz channels 1-11 and 5GHz channels 36, 40, and 44 are safe. */
+/* 2.4GHz channels 1-11 are safe to transmit on everywhere. */
 
 
 /* -- gPXE API: -- */
@@ -272,7 +299,8 @@ struct net80211_wlan *net80211_scan(struct net80211_device *dev);
 
 /** Scans for the given ESSID specifically. Can be used to associate
     with "hidden" networks on the 2.4GHz band. */
-struct net80211_wlan *net80211_probe(struct net80211_device *dev, const char *essid);
+struct net80211_wlan *net80211_probe(struct net80211_device *dev,
+                                    const char *essid);
 
 /** Frees the list returned from a scan or probe call. */
 void net80211_free_netlist(struct net80211_wlan *nets);
@@ -299,6 +327,9 @@ struct io_buffer *net80211_mgmt_dequeue(struct net80211_device *dev);
 
 
 /* -- Driver API: -- */
+/* The 802.11 layer handles the things drivers usually do to the
+   wrapping net_device. Drivers should use the below functions and
+   *not* their net_device analogues on dev->netdev. */
 
 /** Allocates a new 802.11 device with priv_size bytes of
     driver-private data behind its `priv' pointer. This also allocates
@@ -306,16 +337,13 @@ struct io_buffer *net80211_mgmt_dequeue(struct net80211_device *dev);
 struct net80211_device *net80211_alloc(size_t priv_size);
 
 /** Set up an 802.11 device to use the provided operations and
-    hardware information. The hw info will be copied into a
-    dynamically allocated structure that the 802.11 layer takes
-    ownership of; the ops are simply pointed at, and should be defined
-    statically. */
-int net80211_init(struct net80211_device *dev,
-                 struct net80211_device_operations *ops,
-                 struct net80211_hw_info *hw);
-
-/** Register an 802.11 device with the network stack. */
-int net80211_register(struct net80211_device *dev);
+    hardware information, and register it with the network stack. The
+    hw info will be copied into a dynamically allocated structure that
+    the 802.11 layer takes ownership of; the ops are simply pointed
+    at, and should be defined statically. */
+int net80211_register(struct net80211_device *dev,
+                     struct net80211_device_operations *ops,
+                     struct net80211_hw_info *hw);
 
 /** Indicate receipt of a raw packet from the network interface. Takes
     ownership of the iob. */
@@ -324,13 +352,13 @@ int net80211_rx(struct net80211_device *dev, struct io_buffer *iob);
 /** Indicate an error in receiving a packet. Pass iob if you want it
     freed. */
 int net80211_rx_err(struct net80211_device *dev, struct io_buffer *iob,
-                   int errcode);
+                   int rc);
 
 /** Indicate the completed transmission of a packet passed to
-    (*transmit)(), successfully if errcode == 0 and unsuccessfully if
+    (*transmit)(), successfully if rc == 0 and unsuccessfully if
     not. In either case this function takes ownership of the iob. */
 int net80211_tx_complete(struct net80211_device *dev, struct io_buffer *iob,
-                        int errcode);
+                        int rc);
 
 /** Removes the registration of an 802.11 device. */
 void net80211_unregister(struct net80211_device *dev);