802.11 driver interface API


Functions

struct net80211_devicenet80211_alloc (size_t priv_size)
 Allocate 802.11 device.
int net80211_register (struct net80211_device *dev, struct net80211_device_operations *ops, struct net80211_hw_info *hw)
 Register 802.11 device with network stack.
u16 net80211_duration (struct net80211_device *dev, int bytes, u16 rate)
 Calculate one frame's contribution to 802.11 duration field.
void net80211_rx (struct net80211_device *dev, struct io_buffer *iob, int signal, u16 rate)
 Handle receipt of 802.11 frame.
void net80211_rx_err (struct net80211_device *dev, struct io_buffer *iob, int rc)
 Indicate an error in receiving a packet.
void net80211_tx_complete (struct net80211_device *dev, struct io_buffer *iob, int retries, int rc)
 Indicate the completed transmission of a packet.
void net80211_unregister (struct net80211_device *dev)
 Unregister 802.11 device from network stack.
void net80211_free (struct net80211_device *dev)
 Free 802.11 device.

Function Documentation

struct net80211_device* net80211_alloc ( size_t  priv_size  )  [read]

Allocate 802.11 device.

Parameters:
priv_size Size of driver-private allocation area
Return values:
dev Newly allocated 802.11 device
This function allocates a net_device with space in its private area for both the net80211_device it will wrap and the driver-private data space requested. It initializes the link-layer-specific parts of the net_device, and links the net80211_device to the net_device appropriately.

Definition at line 766 of file net80211.c.

References alloc_netdev(), IEEE80211_MAX_DATA_LEN, INIT_LIST_HEAD, net_device::ll_broadcast, net_device::ll_protocol, net_device::max_pkt_len, net80211_device::mgmt_info_queue, net80211_device::mgmt_queue, net80211_ll_broadcast, net80211_null_ops, net80211_step_associate(), net80211_device::netdev, netdev, netdev_init(), NULL, net80211_device::op, net80211_device::priv, net_device::priv, net80211_device::proc_assoc, process_init_stopped(), net_device::refcnt, and u8.

Referenced by ath5k_probe(), and rtl818x_probe().

00767 {
00768         struct net80211_device *dev;
00769         struct net_device *netdev =
00770                 alloc_netdev ( sizeof ( *dev ) + priv_size );
00771 
00772         if ( ! netdev )
00773                 return NULL;
00774 
00775         netdev->ll_protocol = &net80211_ll_protocol;
00776         netdev->ll_broadcast = net80211_ll_broadcast;
00777         netdev->max_pkt_len = IEEE80211_MAX_DATA_LEN;
00778         netdev_init ( netdev, &net80211_netdev_ops );
00779 
00780         dev = netdev->priv;
00781         dev->netdev = netdev;
00782         dev->priv = ( u8 * ) dev + sizeof ( *dev );
00783         dev->op = &net80211_null_ops;
00784 
00785         process_init_stopped ( &dev->proc_assoc, net80211_step_associate,
00786                                &netdev->refcnt );
00787         INIT_LIST_HEAD ( &dev->mgmt_queue );
00788         INIT_LIST_HEAD ( &dev->mgmt_info_queue );
00789 
00790         return dev;
00791 }

int net80211_register ( struct net80211_device dev,
struct net80211_device_operations ops,
struct net80211_hw_info hw 
)

Register 802.11 device with network stack.

Parameters:
dev 802.11 device
ops 802.11 device operations
hw 802.11 hardware information
This also registers the wrapping net_device with the higher network layers.

Definition at line 803 of file net80211.c.

References net80211_device::channel, net80211_hw_info::channels, net80211_device::channels, ENOMEM, ETH_ALEN, net80211_device::hw, net_device::hw_addr, net80211_hw_info::hwaddr, net80211_device::list, list_add_tail, malloc(), memcpy, NET80211_MAX_CHANNELS, net80211_device::netdev, net80211_device::op, and register_netdev().

Referenced by ath5k_attach(), and rtl818x_probe().

00806 {
00807         dev->op = ops;
00808         dev->hw = malloc ( sizeof ( *hw ) );
00809         if ( ! dev->hw )
00810                 return -ENOMEM;
00811 
00812         memcpy ( dev->hw, hw, sizeof ( *hw ) );
00813         memcpy ( dev->netdev->hw_addr, hw->hwaddr, ETH_ALEN );
00814 
00815         /* Set some sensible channel defaults for driver's open() function */
00816         memcpy ( dev->channels, dev->hw->channels,
00817                  NET80211_MAX_CHANNELS * sizeof ( dev->channels[0] ) );
00818         dev->channel = 0;
00819 
00820         list_add_tail ( &dev->list, &net80211_devices );
00821         return register_netdev ( dev->netdev );
00822 }

u16 net80211_duration ( struct net80211_device dev,
int  bytes,
u16  rate 
)

Calculate one frame's contribution to 802.11 duration field.

Parameters:
dev 802.11 device
bytes Amount of data to calculate duration for
Return values:
dur Duration field in microseconds
To avoid multiple stations attempting to transmit at once, 802.11 provides that every packet shall include a duration field specifying a length of time for which the wireless medium will be reserved after it is transmitted. The duration is measured in microseconds and is calculated with respect to the current physical-layer parameters of the 802.11 device.

For an unfragmented data or management frame, or the last fragment of a fragmented frame, the duration captures only the 10 data bytes of one ACK; call once with bytes = 10.

For a fragment of a data or management rame that will be followed by more fragments, the duration captures an ACK, the following fragment, and its ACK; add the results of three calls, two with bytes = 10 and one with bytes set to the next fragment's size.

For an RTS control frame, the duration captures the responding CTS, the frame being sent, and its ACK; add the results of three calls, two with bytes = 10 and one with bytes set to the next frame's size (assuming unfragmented).

For a CTS-to-self control frame, the duration captures the frame being protected and its ACK; add the results of two calls, one with bytes = 10 and one with bytes set to the next frame's size.

No other frame types are currently supported by gPXE.

Definition at line 464 of file net80211.c.

References net80211_channel::band, net80211_device::channel, net80211_device::channels, NET80211_BAND_5GHZ, NET80211_PHY_USE_SHORT_PREAMBLE, net80211_rate_is_erp(), net80211_device::phy_flags, and u32.

Referenced by ath5k_hw_write_rate_duration(), net80211_cts_duration(), net80211_ll_push(), and net80211_tx_mgmt().

00465 {
00466         struct net80211_channel *chan = &dev->channels[dev->channel];
00467         u32 kbps = rate * 100;
00468 
00469         if ( chan->band == NET80211_BAND_5GHZ || net80211_rate_is_erp ( rate ) ) {
00470                 /* OFDM encoding (802.11a/g) */
00471                 int bits_per_symbol = ( kbps * 4 ) / 1000;      /* 4us/symbol */
00472                 int bits = 22 + ( bytes << 3 ); /* 22-bit PLCP */
00473                 int symbols = ( bits + bits_per_symbol - 1 ) / bits_per_symbol;
00474 
00475                 return 16 + 20 + ( symbols * 4 ); /* 16us SIFS, 20us preamble */
00476         } else {
00477                 /* CCK encoding (802.11b) */
00478                 int phy_time = 144 + 48;        /* preamble + PLCP */
00479                 int bits = bytes << 3;
00480                 int data_time = ( bits * 1000 + kbps - 1 ) / kbps;
00481 
00482                 if ( dev->phy_flags & NET80211_PHY_USE_SHORT_PREAMBLE )
00483                         phy_time >>= 1;
00484 
00485                 return 10 + phy_time + data_time; /* 10us SIFS */
00486         }
00487 }

void net80211_rx ( struct net80211_device dev,
struct io_buffer iob,
int  signal,
u16  rate 
)

Handle receipt of 802.11 frame.

Parameters:
dev 802.11 device
iob I/O buffer
signal Received signal strength
rate Bitrate at which frame was received, in 100 kbps units
If the rate or signal is unknown, 0 should be passed.

Definition at line 2702 of file net80211.c.

References ieee80211_frame::addr1, ieee80211_frame::addr2, net80211_device::bssid, net80211_device::crypto, io_buffer::data, DBGC, DBGC2, net80211_crypto::decrypt, EINVAL_CRYPTO_REQUEST, ETH_ALEN, ieee80211_frame::fc, net80211_hw_info::flags, free_iob(), net80211_device::gcrypto, net80211_device::hw, IEEE80211_FC_MORE_FRAG, IEEE80211_FC_PROTECTED, IEEE80211_FC_RETRY, IEEE80211_FC_SUBTYPE, IEEE80211_FC_TYPE, IEEE80211_FC_VERSION, IEEE80211_FRAG, IEEE80211_STYPE_DATA, IEEE80211_THIS_VERSION, IEEE80211_TYPE_CTRL, IEEE80211_TYPE_MGMT, iob_unput, net80211_device::last_rx_seq, net80211_device::last_signal, memcmp(), NET80211_ASSOCIATED, net80211_handle_mgmt(), net80211_rx_frag(), net80211_device::netdev, netdev_rx(), netdev_rx_err(), NULL, rc80211_update_rx(), net80211_device::rctl, ieee80211_frame::seq, net80211_device::state, and u16.

Referenced by ath5k_handle_rx(), net80211_rx_frag(), and rtl818x_handle_rx().

02704 {
02705         struct ieee80211_frame *hdr = iob->data;
02706         u16 type = hdr->fc & IEEE80211_FC_TYPE;
02707         if ( ( hdr->fc & IEEE80211_FC_VERSION ) != IEEE80211_THIS_VERSION )
02708                 goto drop;      /* drop invalid-version packets */
02709 
02710         if ( type == IEEE80211_TYPE_CTRL )
02711                 goto drop;      /* we don't handle control packets,
02712                                    the hardware does */
02713 
02714         if ( dev->last_rx_seq == hdr->seq )
02715                 goto drop;      /* avoid duplicate packet */
02716         dev->last_rx_seq = hdr->seq;
02717 
02718         if ( dev->hw->flags & NET80211_HW_RX_HAS_FCS ) {
02719                 /* discard the FCS */
02720                 iob_unput ( iob, 4 );
02721         }
02722 
02723         /* Only decrypt packets from our BSSID, to avoid spurious errors */
02724         if ( ( hdr->fc & IEEE80211_FC_PROTECTED ) &&
02725              ! memcmp ( hdr->addr2, dev->bssid, ETH_ALEN ) ) {
02726                 /* Decrypt packet; record and drop if it fails */
02727                 struct io_buffer *niob;
02728                 struct net80211_crypto *crypto = dev->crypto;
02729 
02730                 if ( ! dev->crypto ) {
02731                         DBGC ( dev, "802.11 %p cannot decrypt packet "
02732                                "without a cryptosystem\n", dev );
02733                         goto drop_crypt;
02734                 }
02735 
02736                 if ( ( hdr->addr1[0] & 1 ) && dev->gcrypto ) {
02737                         /* Use group decryption if needed */
02738                         crypto = dev->gcrypto;
02739                 }
02740 
02741                 niob = crypto->decrypt ( crypto, iob );
02742                 if ( ! niob ) {
02743                         DBGC ( dev, "802.11 %p decryption error\n", dev );
02744                         goto drop_crypt;
02745                 }
02746                 free_iob ( iob );
02747                 iob = niob;
02748         }
02749 
02750         dev->last_signal = signal;
02751 
02752         /* Fragments go into the frag cache or get dropped. */
02753         if ( IEEE80211_FRAG ( hdr->seq ) != 0
02754              || ( hdr->fc & IEEE80211_FC_MORE_FRAG ) ) {
02755                 net80211_rx_frag ( dev, iob, signal );
02756                 return;
02757         }
02758 
02759         /* Management frames get handled, enqueued, or dropped. */
02760         if ( type == IEEE80211_TYPE_MGMT ) {
02761                 net80211_handle_mgmt ( dev, iob, signal );
02762                 return;
02763         }
02764 
02765         /* Data frames get dropped or sent to the net_device. */
02766         if ( ( hdr->fc & IEEE80211_FC_SUBTYPE ) != IEEE80211_STYPE_DATA )
02767                 goto drop;      /* drop QoS, CFP, or null data packets */
02768 
02769         /* Update rate-control algorithm */
02770         if ( dev->rctl )
02771                 rc80211_update_rx ( dev, hdr->fc & IEEE80211_FC_RETRY, rate );
02772 
02773         /* Pass packet onward */
02774         if ( dev->state & NET80211_ASSOCIATED ) {
02775                 netdev_rx ( dev->netdev, iob );
02776                 return;
02777         }
02778 
02779         /* No association? Drop it. */
02780         goto drop;
02781 
02782  drop_crypt:
02783         netdev_rx_err ( dev->netdev, NULL, EINVAL_CRYPTO_REQUEST );
02784  drop:
02785         DBGC2 ( dev, "802.11 %p dropped packet fc=%04x seq=%04x\n", dev,
02786                 hdr->fc, hdr->seq );
02787         free_iob ( iob );
02788         return;
02789 }

void net80211_rx_err ( struct net80211_device dev,
struct io_buffer iob,
int  rc 
)

Indicate an error in receiving a packet.

Parameters:
dev 802.11 device
iob I/O buffer with received packet, or NULL
rc Error code
This logs the error with the wrapping net_device, and frees iob if it is passed.

Definition at line 2800 of file net80211.c.

References net80211_device::netdev, and netdev_rx_err().

Referenced by ath5k_handle_rx(), and rtl818x_handle_rx().

02802 {
02803         netdev_rx_err ( dev->netdev, iob, rc );
02804 }

void net80211_tx_complete ( struct net80211_device dev,
struct io_buffer iob,
int  retries,
int  rc 
)

Indicate the completed transmission of a packet.

Parameters:
dev 802.11 device
iob I/O buffer of transmitted packet
retries Number of times this packet was retransmitted
rc Error code, or 0 for success
This logs an error with the wrapping net_device if one occurred, and removes and frees the I/O buffer from its TX queue. The provided retry information is used to tune our transmission rate.

If the packet did not need to be retransmitted because it was properly ACKed the first time, retries should be 0.

Definition at line 2820 of file net80211.c.

References net80211_device::netdev, netdev_tx_complete_err(), rc80211_update_tx(), and net80211_device::rctl.

Referenced by ath5k_tx_processq(), ath5k_txbuf_free(), rtl818x_free_tx_ring(), and rtl818x_handle_tx().

02822 {
02823         /* Update rate-control algorithm */
02824         if ( dev->rctl )
02825                 rc80211_update_tx ( dev, retries, rc );
02826 
02827         /* Pass completion onward */
02828         netdev_tx_complete_err ( dev->netdev, iob, rc );
02829 }

void net80211_unregister ( struct net80211_device dev  ) 

Unregister 802.11 device from network stack.

Parameters:
dev 802.11 device
After this call, the device operations are cleared so that they will not be called.

Definition at line 832 of file net80211.c.

References net80211_device::list, list_del, net80211_null_ops, net80211_device::netdev, net80211_device::op, and unregister_netdev().

Referenced by ath5k_detach(), and rtl818x_remove().

00833 {
00834         unregister_netdev ( dev->netdev );
00835         list_del ( &dev->list );
00836         dev->op = &net80211_null_ops;
00837 }

void net80211_free ( struct net80211_device dev  ) 

Free 802.11 device.

Parameters:
dev 802.11 device
The device should be unregistered before this function is called.

Definition at line 846 of file net80211.c.

References free(), net80211_device::hw, net80211_device::netdev, netdev_nullify(), netdev_put(), rc80211_free(), and net80211_device::rctl.

Referenced by ath5k_probe(), ath5k_remove(), rtl818x_probe(), and rtl818x_remove().

00847 {
00848         free ( dev->hw );
00849         rc80211_free ( dev->rctl );
00850         netdev_nullify ( dev->netdev );
00851         netdev_put ( dev->netdev );
00852 }


Generated on Tue Apr 6 20:01:59 2010 for gPXE by  doxygen 1.5.7.1