What this layer should do
- It mantain the old mechanism as alternative, so the
ipw2100 driver works with really few changes.
- Encapsulate / Decapsulate rtllib packet
- Handle fragmentation
- Optionally provide an alterantive mechanism for netif queue stop/wake,
so that the rtllib layer will pass one fragment per time instead of
one txb struct per time. so the driver can stop the queue in the middle
of a packet.
- Provide two different TX interfaces for cards that can handle management
frames on one HW queue, and data on another, and for cards that have only
one HW queue (the latter untested and very, very rough).
- Optionally provide the logic for handling IBSS/MASTER/MONITOR/BSS modes
and for the channel, essid and wap get/set wireless extension requests.
so that the driver has only to change channel when the ieee stack tell it.
- Optionally provide a scanning mechanism so that the driver has not to
worry about this, just implement the set channel calback and pass
frames to the upper layer
- Optionally provide the bss client protocol handshaking (just with open
authentication)
- Optionally provide the probe request send mechanism
- Optionally provide the bss master mode logic to handle association
protocol (only open authentication) and probe responses.
- SW wep encryption (with open authentication)
- It collects some stats
- It provides beacons to the card when it ask for them
What this layer doesn't do (yet)
- Perform shared authentication
- Have full support for master mode (the AP should loop back in the air
frames from an associated client to another. This could be done easily
with few lines of code, and it is done in my previous version of the
stach, but a table of association must be keept and a disassociation
policy must be decided and implemented.
- Handle cleanly the full ieee 802.11 protocol. In AP mode it never
disassociate clients, and it is really prone to always allow access.
In bss client mode it is a bit rough with AP deauth and disassoc requests.
- It has not any entry point to view the collected stats.
- Altought it takes care of the card supported rates in the management frame
it sends, support for rate changing on TXed packet is not complete.
- Give up once associated in bss client mode (it never detect a
signal loss condition to disassociate and restart scanning)
- Provide a mechanism for enabling the TX in monitor mode, so
userspace programs can TX raw packets.
- Provide a mechanism for cards that need that the SW take care of beacon
TX completely, in sense that the SW has to enqueue by itself beacons
to the card so it TX them (if any...)
APIs
Callback functions in the original stack has been mantained.
following has been added (from rtllib.h)
/* Softmac-generated frames (mamagement) are TXed via this
* callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is
* not set. As some cards may have different HW queues that
* one might want to use for data and management frames
* the option to have two callbacks might be useful.
* This fucntion can't sleep.
*/
int (*softmac_hard_start_xmit)(struct sk_buff *skb,
struct net_device *dev);
/* used instead of hard_start_xmit (not softmac_hard_start_xmit)
* if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data
* frames. I the option IEEE_SOFTMAC_SINGLE_QUEUE is also set
* then also management frames are sent via this callback.
* This function can't sleep.
*/
void (*softmac_data_hard_start_xmit)(struct sk_buff *skb,
struct net_device *dev);
/* stops the HW queue for DATA frames. Useful to avoid
* waste time to TX data frame when we are reassociating
* This function can sleep.
*/
void (*data_hard_stop)(struct net_device *dev);
/* OK this is complementar to data_poll_hard_stop */
void (*data_hard_resume)(struct net_device *dev);
/* ask to the driver to retune the radio .
* This function can sleep. the driver should ensure
* the radio has been swithced before return.
*/
void (*set_chan)(struct net_device *dev,short ch);
/* These are not used if the ieee stack takes care of
* scanning (IEEE_SOFTMAC_SCAN feature set).
* In this case only the set_chan is used.
*
* The syncro version is similar to the start_scan but
* does not return until all channels has been scanned.
* this is called in user context and should sleep,
* it is called in a work_queue when swithcing to ad-hoc mode
* or in behalf of iwlist scan when the card is associated
* and root user ask for a scan.
* the fucntion stop_scan should stop both the syncro and
* background scanning and can sleep.
* The fucntion start_scan should initiate the background
* scanning and can't sleep.
*/
void (*scan_syncro)(struct net_device *dev);
void (*start_scan)(struct net_device *dev);
void (*stop_scan)(struct net_device *dev);
/* indicate the driver that the link state is changed
* for example it may indicate the card is associated now.
* Driver might be interested in this to apply RX filter
* rules or simply light the LINK led
*/
void (*link_change)(struct net_device *dev);
Functions hard_data_[resume/stop] are optional and should not be used
if the driver decides to uses data+management frames enqueue in a
single HQ queue (thus using just the softmac_hard_data_start_xmit
callback).
Function that the driver can use are:
rtllib_get_beacon - this is called by the driver when
the HW needs a beacon.
rtllib_softmac_start_protocol - this should normally be called in the
driver open function
rtllib_softmac_stop_protocol - the opposite of the above
rtllib_wake_queue - this is similar to netif_wake_queue
rtllib_reset_queue - this throw away fragments pending(if any)
rtllib_stop_queue - this is similar to netif_stop_queue
known BUGS:
- When performing syncro scan (possiblily when swithcing to ad-hoc mode
and when running iwlist scan when associated) there is still an odd
behaviour.. I have not looked in this more accurately (yet).
locking:
locking is done by means of three structures.
1- ieee->lock (by means of spin_[un]lock_irq[save/restore]
2- ieee->wx_sem
3- ieee->scan_sem
the lock 1 is what protect most of the critical sections in the ieee stack.
the lock 2 is used to avoid that more than one of the SET wireless extension
handlers (as well as start/stop protocol function) are running at the same time.
the lock 1 is used when we need to modify or read the shared data in the wx handlers.
In other words the lock 2 will prevent one SET action will run across another SET
action (by make sleep the 2nd one) but allow GET actions, while the lock 1
make atomic those little shared data access in both GET and SET operation.
So get operation will be never be delayed really: they will never sleep..
Furthermore in the top of some SET operations a flag is set before acquiring
the lock. This is an help to make the previous running SET operation to
finish faster if needed (just in case the second one will totally undo the
first, so there is not need to complete the 1st really.. ).
The background scanning mechaninsm is protected by the lock 1 except for the
workqueue. this wq is here just to let the set_chan callback sleep (I thinked it
might be appreciated by USB network card driver developer). In this case the lock 3
take its turn.
Thus the stop function needs both the locks.
Funny in the syncro scan the lock 2 play its role (as both the syncro_scan
function and the stop scan function are called with this semaphore held).