Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6

* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6: (217 commits)
  net/ieee80211: fix more crypto-related build breakage
  [PATCH] Spidernet: add ethtool -S (show statistics)
  [NET] GT96100: Delete bitrotting ethernet driver
  [PATCH] mv643xx_eth: restrict to 32-bit PPC_MULTIPLATFORM
  [PATCH] Cirrus Logic ep93xx ethernet driver
  r8169: the MMIO region of the 8167 stands behin BAR#1
  e1000, ixgb: Remove pointless wrappers
  [PATCH] Remove powerpc specific parts of 3c509 driver
  [PATCH] s2io: Switch to pci_get_device
  [PATCH] gt96100: move to pci_get_device API
  [PATCH] ehea: bugfix for register access functions
  [PATCH] e1000 disable device on PCI error
  drivers/net/phy/fixed: #if 0 some incomplete code
  drivers/net: const-ify ethtool_ops declarations
  [PATCH] ethtool: allow const ethtool_ops
  [PATCH] sky2: big endian
  [PATCH] sky2: fiber support
  [PATCH] sky2: tx pause bug fix
  drivers/net: Trim trailing whitespace
  [PATCH] ehea: IBM eHEA Ethernet Device Driver
  ...

Manually resolved conflicts in drivers/net/ixgb/ixgb_main.c and
drivers/net/sky2.c related to CHECKSUM_HW/CHECKSUM_PARTIAL changes by
commit 84fa7933a3 that just happened to be
next to unrelated changes in this update.
This commit is contained in:
Linus Torvalds 2006-09-24 10:15:13 -07:00
commit a319a2773a
360 changed files with 40596 additions and 28263 deletions

View file

@ -143,7 +143,7 @@ static int ethtool_set_settings(struct net_device *dev, void __user *useraddr)
static int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr)
{
struct ethtool_drvinfo info;
struct ethtool_ops *ops = dev->ethtool_ops;
const struct ethtool_ops *ops = dev->ethtool_ops;
if (!ops->get_drvinfo)
return -EOPNOTSUPP;
@ -169,7 +169,7 @@ static int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr)
static int ethtool_get_regs(struct net_device *dev, char __user *useraddr)
{
struct ethtool_regs regs;
struct ethtool_ops *ops = dev->ethtool_ops;
const struct ethtool_ops *ops = dev->ethtool_ops;
void *regbuf;
int reglen, ret;
@ -282,7 +282,7 @@ static int ethtool_get_link(struct net_device *dev, void __user *useraddr)
static int ethtool_get_eeprom(struct net_device *dev, void __user *useraddr)
{
struct ethtool_eeprom eeprom;
struct ethtool_ops *ops = dev->ethtool_ops;
const struct ethtool_ops *ops = dev->ethtool_ops;
u8 *data;
int ret;
@ -327,7 +327,7 @@ static int ethtool_get_eeprom(struct net_device *dev, void __user *useraddr)
static int ethtool_set_eeprom(struct net_device *dev, void __user *useraddr)
{
struct ethtool_eeprom eeprom;
struct ethtool_ops *ops = dev->ethtool_ops;
const struct ethtool_ops *ops = dev->ethtool_ops;
u8 *data;
int ret;
@ -640,7 +640,7 @@ static int ethtool_set_gso(struct net_device *dev, char __user *useraddr)
static int ethtool_self_test(struct net_device *dev, char __user *useraddr)
{
struct ethtool_test test;
struct ethtool_ops *ops = dev->ethtool_ops;
const struct ethtool_ops *ops = dev->ethtool_ops;
u64 *data;
int ret;
@ -673,7 +673,7 @@ static int ethtool_self_test(struct net_device *dev, char __user *useraddr)
static int ethtool_get_strings(struct net_device *dev, void __user *useraddr)
{
struct ethtool_gstrings gstrings;
struct ethtool_ops *ops = dev->ethtool_ops;
const struct ethtool_ops *ops = dev->ethtool_ops;
u8 *data;
int ret;
@ -733,7 +733,7 @@ static int ethtool_phys_id(struct net_device *dev, void __user *useraddr)
static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)
{
struct ethtool_stats stats;
struct ethtool_ops *ops = dev->ethtool_ops;
const struct ethtool_ops *ops = dev->ethtool_ops;
u64 *data;
int ret;

View file

@ -263,6 +263,27 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
return 0;
}
/*
* deal with seq counter wrapping correctly.
* refer to timer_after() for jiffies wrapping handling
*/
static inline int ccmp_replay_check(u8 *pn_n, u8 *pn_o)
{
u32 iv32_n, iv16_n;
u32 iv32_o, iv16_o;
iv32_n = (pn_n[0] << 24) | (pn_n[1] << 16) | (pn_n[2] << 8) | pn_n[3];
iv16_n = (pn_n[4] << 8) | pn_n[5];
iv32_o = (pn_o[0] << 24) | (pn_o[1] << 16) | (pn_o[2] << 8) | pn_o[3];
iv16_o = (pn_o[4] << 8) | pn_o[5];
if ((s32)iv32_n - (s32)iv32_o < 0 ||
(iv32_n == iv32_o && iv16_n <= iv16_o))
return 1;
return 0;
}
static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
{
struct ieee80211_ccmp_data *key = priv;
@ -315,7 +336,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
pn[5] = pos[0];
pos += 8;
if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) {
if (ccmp_replay_check(pn, key->rx_pn)) {
if (net_ratelimit()) {
printk(KERN_DEBUG "CCMP: replay detected: STA=" MAC_FMT
" previous PN %02x%02x%02x%02x%02x%02x "

View file

@ -53,8 +53,10 @@ struct ieee80211_tkip_data {
int key_idx;
struct crypto_blkcipher *tfm_arc4;
struct crypto_hash *tfm_michael;
struct crypto_blkcipher *rx_tfm_arc4;
struct crypto_hash *rx_tfm_michael;
struct crypto_blkcipher *tx_tfm_arc4;
struct crypto_hash *tx_tfm_michael;
/* scratch buffers for virt_to_page() (crypto API) */
u8 rx_hdr[16], tx_hdr[16];
@ -86,21 +88,39 @@ static void *ieee80211_tkip_init(int key_idx)
priv->key_idx = key_idx;
priv->tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
CRYPTO_ALG_ASYNC);
if (IS_ERR(priv->tfm_arc4)) {
if (IS_ERR(priv->tx_tfm_arc4)) {
printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
"crypto API arc4\n");
priv->tfm_arc4 = NULL;
priv->tx_tfm_arc4 = NULL;
goto fail;
}
priv->tfm_michael = crypto_alloc_hash("michael_mic", 0,
CRYPTO_ALG_ASYNC);
if (IS_ERR(priv->tfm_michael)) {
priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
CRYPTO_ALG_ASYNC);
if (IS_ERR(priv->tx_tfm_michael)) {
printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
"crypto API michael_mic\n");
priv->tfm_michael = NULL;
priv->tx_tfm_michael = NULL;
goto fail;
}
priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
CRYPTO_ALG_ASYNC);
if (IS_ERR(priv->rx_tfm_arc4)) {
printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
"crypto API arc4\n");
priv->rx_tfm_arc4 = NULL;
goto fail;
}
priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
CRYPTO_ALG_ASYNC);
if (IS_ERR(priv->rx_tfm_michael)) {
printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
"crypto API michael_mic\n");
priv->rx_tfm_michael = NULL;
goto fail;
}
@ -108,10 +128,14 @@ static void *ieee80211_tkip_init(int key_idx)
fail:
if (priv) {
if (priv->tfm_michael)
crypto_free_hash(priv->tfm_michael);
if (priv->tfm_arc4)
crypto_free_blkcipher(priv->tfm_arc4);
if (priv->tx_tfm_michael)
crypto_free_hash(priv->tx_tfm_michael);
if (priv->tx_tfm_arc4)
crypto_free_blkcipher(priv->tx_tfm_arc4);
if (priv->rx_tfm_michael)
crypto_free_hash(priv->rx_tfm_michael);
if (priv->rx_tfm_arc4)
crypto_free_blkcipher(priv->rx_tfm_arc4);
kfree(priv);
}
@ -121,10 +145,16 @@ static void *ieee80211_tkip_init(int key_idx)
static void ieee80211_tkip_deinit(void *priv)
{
struct ieee80211_tkip_data *_priv = priv;
if (_priv && _priv->tfm_michael)
crypto_free_hash(_priv->tfm_michael);
if (_priv && _priv->tfm_arc4)
crypto_free_blkcipher(_priv->tfm_arc4);
if (_priv) {
if (_priv->tx_tfm_michael)
crypto_free_hash(_priv->tx_tfm_michael);
if (_priv->tx_tfm_arc4)
crypto_free_blkcipher(_priv->tx_tfm_arc4);
if (_priv->rx_tfm_michael)
crypto_free_hash(_priv->rx_tfm_michael);
if (_priv->rx_tfm_arc4)
crypto_free_blkcipher(_priv->rx_tfm_arc4);
}
kfree(priv);
}
@ -323,7 +353,7 @@ static int ieee80211_tkip_hdr(struct sk_buff *skb, int hdr_len,
static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
{
struct ieee80211_tkip_data *tkey = priv;
struct blkcipher_desc desc = { .tfm = tkey->tfm_arc4 };
struct blkcipher_desc desc = { .tfm = tkey->tx_tfm_arc4 };
int len;
u8 rc4key[16], *pos, *icv;
u32 crc;
@ -357,17 +387,30 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
icv[2] = crc >> 16;
icv[3] = crc >> 24;
crypto_blkcipher_setkey(tkey->tfm_arc4, rc4key, 16);
crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
sg.page = virt_to_page(pos);
sg.offset = offset_in_page(pos);
sg.length = len + 4;
return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
}
/*
* deal with seq counter wrapping correctly.
* refer to timer_after() for jiffies wrapping handling
*/
static inline int tkip_replay_check(u32 iv32_n, u16 iv16_n,
u32 iv32_o, u16 iv16_o)
{
if ((s32)iv32_n - (s32)iv32_o < 0 ||
(iv32_n == iv32_o && iv16_n <= iv16_o))
return 1;
return 0;
}
static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
{
struct ieee80211_tkip_data *tkey = priv;
struct blkcipher_desc desc = { .tfm = tkey->tfm_arc4 };
struct blkcipher_desc desc = { .tfm = tkey->rx_tfm_arc4 };
u8 rc4key[16];
u8 keyidx, *pos;
u32 iv32;
@ -419,8 +462,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
pos += 8;
if (iv32 < tkey->rx_iv32 ||
(iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
if (tkip_replay_check(iv32, iv16, tkey->rx_iv32, tkey->rx_iv16)) {
if (net_ratelimit()) {
printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT
" previous TSC %08x%04x received TSC "
@ -439,7 +481,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
plen = skb->len - hdr_len - 12;
crypto_blkcipher_setkey(tkey->tfm_arc4, rc4key, 16);
crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
sg.page = virt_to_page(pos);
sg.offset = offset_in_page(pos);
sg.length = plen + 4;
@ -484,13 +526,13 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
return keyidx;
}
static int michael_mic(struct ieee80211_tkip_data *tkey, u8 * key, u8 * hdr,
static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
u8 * data, size_t data_len, u8 * mic)
{
struct hash_desc desc;
struct scatterlist sg[2];
if (tkey->tfm_michael == NULL) {
if (tfm_michael == NULL) {
printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
return -1;
}
@ -502,10 +544,10 @@ static int michael_mic(struct ieee80211_tkip_data *tkey, u8 * key, u8 * hdr,
sg[1].offset = offset_in_page(data);
sg[1].length = data_len;
if (crypto_hash_setkey(tkey->tfm_michael, key, 8))
if (crypto_hash_setkey(tfm_michael, key, 8))
return -1;
desc.tfm = tkey->tfm_michael;
desc.tfm = tfm_michael;
desc.flags = 0;
return crypto_hash_digest(&desc, sg, data_len + 16, mic);
}
@ -541,7 +583,7 @@ static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr)
if (stype & IEEE80211_STYPE_QOS_DATA) {
const struct ieee80211_hdr_3addrqos *qoshdr =
(struct ieee80211_hdr_3addrqos *)skb->data;
hdr[12] = le16_to_cpu(qoshdr->qos_ctl) & IEEE80211_QCTL_TID;
hdr[12] = qoshdr->qos_ctl & cpu_to_le16(IEEE80211_QCTL_TID);
} else
hdr[12] = 0; /* priority */
@ -563,7 +605,7 @@ static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len,
michael_mic_hdr(skb, tkey->tx_hdr);
pos = skb_put(skb, 8);
if (michael_mic(tkey, &tkey->key[16], tkey->tx_hdr,
if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
return -1;
@ -601,7 +643,7 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
return -1;
michael_mic_hdr(skb, tkey->rx_hdr);
if (michael_mic(tkey, &tkey->key[24], tkey->rx_hdr,
if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
return -1;
if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
@ -631,14 +673,18 @@ static int ieee80211_tkip_set_key(void *key, int len, u8 * seq, void *priv)
{
struct ieee80211_tkip_data *tkey = priv;
int keyidx;
struct crypto_hash *tfm = tkey->tfm_michael;
struct crypto_blkcipher *tfm2 = tkey->tfm_arc4;
struct crypto_hash *tfm = tkey->tx_tfm_michael;
struct crypto_blkcipher *tfm2 = tkey->tx_tfm_arc4;
struct crypto_hash *tfm3 = tkey->rx_tfm_michael;
struct crypto_blkcipher *tfm4 = tkey->rx_tfm_arc4;
keyidx = tkey->key_idx;
memset(tkey, 0, sizeof(*tkey));
tkey->key_idx = keyidx;
tkey->tfm_michael = tfm;
tkey->tfm_arc4 = tfm2;
tkey->tx_tfm_michael = tfm;
tkey->tx_tfm_arc4 = tfm2;
tkey->rx_tfm_michael = tfm3;
tkey->rx_tfm_arc4 = tfm4;
if (len == TKIP_KEY_LEN) {
memcpy(tkey->key, key, TKIP_KEY_LEN);
tkey->key_set = 1;

View file

@ -33,7 +33,8 @@ struct prism2_wep_data {
u8 key[WEP_KEY_LEN + 1];
u8 key_len;
u8 key_idx;
struct crypto_blkcipher *tfm;
struct crypto_blkcipher *tx_tfm;
struct crypto_blkcipher *rx_tfm;
};
static void *prism2_wep_init(int keyidx)
@ -45,14 +46,21 @@ static void *prism2_wep_init(int keyidx)
goto fail;
priv->key_idx = keyidx;
priv->tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(priv->tfm)) {
priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(priv->tx_tfm)) {
printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
"crypto API arc4\n");
priv->tfm = NULL;
priv->tx_tfm = NULL;
goto fail;
}
priv->rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(priv->rx_tfm)) {
printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
"crypto API arc4\n");
priv->rx_tfm = NULL;
goto fail;
}
/* start WEP IV from a random value */
get_random_bytes(&priv->iv, 4);
@ -60,8 +68,10 @@ static void *prism2_wep_init(int keyidx)
fail:
if (priv) {
if (priv->tfm)
crypto_free_blkcipher(priv->tfm);
if (priv->tx_tfm)
crypto_free_blkcipher(priv->tx_tfm);
if (priv->rx_tfm)
crypto_free_blkcipher(priv->rx_tfm);
kfree(priv);
}
return NULL;
@ -70,8 +80,12 @@ static void *prism2_wep_init(int keyidx)
static void prism2_wep_deinit(void *priv)
{
struct prism2_wep_data *_priv = priv;
if (_priv && _priv->tfm)
crypto_free_blkcipher(_priv->tfm);
if (_priv) {
if (_priv->tx_tfm)
crypto_free_blkcipher(_priv->tx_tfm);
if (_priv->rx_tfm)
crypto_free_blkcipher(_priv->rx_tfm);
}
kfree(priv);
}
@ -122,7 +136,7 @@ static int prism2_wep_build_iv(struct sk_buff *skb, int hdr_len,
static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
{
struct prism2_wep_data *wep = priv;
struct blkcipher_desc desc = { .tfm = wep->tfm };
struct blkcipher_desc desc = { .tfm = wep->tx_tfm };
u32 crc, klen, len;
u8 *pos, *icv;
struct scatterlist sg;
@ -154,7 +168,7 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
icv[2] = crc >> 16;
icv[3] = crc >> 24;
crypto_blkcipher_setkey(wep->tfm, key, klen);
crypto_blkcipher_setkey(wep->tx_tfm, key, klen);
sg.page = virt_to_page(pos);
sg.offset = offset_in_page(pos);
sg.length = len + 4;
@ -171,7 +185,7 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
{
struct prism2_wep_data *wep = priv;
struct blkcipher_desc desc = { .tfm = wep->tfm };
struct blkcipher_desc desc = { .tfm = wep->rx_tfm };
u32 crc, klen, plen;
u8 key[WEP_KEY_LEN + 3];
u8 keyidx, *pos, icv[4];
@ -196,7 +210,7 @@ static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
/* Apply RC4 to data and compute CRC32 over decrypted data */
plen = skb->len - hdr_len - 8;
crypto_blkcipher_setkey(wep->tfm, key, klen);
crypto_blkcipher_setkey(wep->rx_tfm, key, klen);
sg.page = virt_to_page(pos);
sg.offset = offset_in_page(pos);
sg.length = plen + 4;

View file

@ -779,33 +779,44 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
return 0;
}
/* Filter out unrelated packets, call ieee80211_rx[_mgt] */
int ieee80211_rx_any(struct ieee80211_device *ieee,
/* Filter out unrelated packets, call ieee80211_rx[_mgt]
* This function takes over the skb, it should not be used again after calling
* this function. */
void ieee80211_rx_any(struct ieee80211_device *ieee,
struct sk_buff *skb, struct ieee80211_rx_stats *stats)
{
struct ieee80211_hdr_4addr *hdr;
int is_packet_for_us;
u16 fc;
if (ieee->iw_mode == IW_MODE_MONITOR)
return ieee80211_rx(ieee, skb, stats) ? 0 : -EINVAL;
if (ieee->iw_mode == IW_MODE_MONITOR) {
if (!ieee80211_rx(ieee, skb, stats))
dev_kfree_skb_irq(skb);
return;
}
if (skb->len < sizeof(struct ieee80211_hdr))
goto drop_free;
hdr = (struct ieee80211_hdr_4addr *)skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
if ((fc & IEEE80211_FCTL_VERS) != 0)
return -EINVAL;
goto drop_free;
switch (fc & IEEE80211_FCTL_FTYPE) {
case IEEE80211_FTYPE_MGMT:
if (skb->len < sizeof(struct ieee80211_hdr_3addr))
goto drop_free;
ieee80211_rx_mgt(ieee, hdr, stats);
return 0;
dev_kfree_skb_irq(skb);
return;
case IEEE80211_FTYPE_DATA:
break;
case IEEE80211_FTYPE_CTL:
return 0;
return;
default:
return -EINVAL;
return;
}
is_packet_for_us = 0;
@ -849,8 +860,14 @@ int ieee80211_rx_any(struct ieee80211_device *ieee,
}
if (is_packet_for_us)
return (ieee80211_rx(ieee, skb, stats) ? 0 : -EINVAL);
return 0;
if (!ieee80211_rx(ieee, skb, stats))
dev_kfree_skb_irq(skb);
return;
drop_free:
dev_kfree_skb_irq(skb);
ieee->stats.rx_dropped++;
return;
}
#define MGMT_FRAME_FIXED_PART_LENGTH 0x24
@ -1061,13 +1078,16 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
while (length >= sizeof(*info_element)) {
if (sizeof(*info_element) + info_element->len > length) {
IEEE80211_DEBUG_MGMT("Info elem: parse failed: "
"info_element->len + 2 > left : "
"info_element->len+2=%zd left=%d, id=%d.\n",
info_element->len +
sizeof(*info_element),
length, info_element->id);
return 1;
IEEE80211_ERROR("Info elem: parse failed: "
"info_element->len + 2 > left : "
"info_element->len+2=%zd left=%d, id=%d.\n",
info_element->len +
sizeof(*info_element),
length, info_element->id);
/* We stop processing but don't return an error here
* because some misbehaviour APs break this rule. ie.
* Orinoco AP1000. */
break;
}
switch (info_element->id) {
@ -1166,6 +1186,7 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
case MFIE_TYPE_ERP_INFO:
network->erp_value = info_element->data[0];
network->flags |= NETWORK_HAS_ERP_VALUE;
IEEE80211_DEBUG_MGMT("MFIE_TYPE_ERP_SET: %d\n",
network->erp_value);
break;
@ -1729,5 +1750,6 @@ void ieee80211_rx_mgt(struct ieee80211_device *ieee,
}
}
EXPORT_SYMBOL_GPL(ieee80211_rx_any);
EXPORT_SYMBOL(ieee80211_rx_mgt);
EXPORT_SYMBOL(ieee80211_rx);

View file

@ -337,7 +337,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
hdr_len += 2;
skb->priority = ieee80211_classify(skb);
header.qos_ctl |= skb->priority & IEEE80211_QCTL_TID;
header.qos_ctl |= cpu_to_le16(skb->priority & IEEE80211_QCTL_TID);
}
header.frame_ctl = cpu_to_le16(fc);
@ -532,13 +532,6 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
return 0;
}
if (ret == NETDEV_TX_BUSY) {
printk(KERN_ERR "%s: NETDEV_TX_BUSY returned; "
"driver should report queue full via "
"ieee_device->is_queue_full.\n",
ieee->dev->name);
}
ieee80211_txb_free(txb);
}

View file

@ -96,7 +96,7 @@ ieee80211softmac_disassoc(struct ieee80211softmac_device *mac)
mac->associated = 0;
mac->associnfo.bssvalid = 0;
mac->associnfo.associating = 0;
ieee80211softmac_init_txrates(mac);
ieee80211softmac_init_bss(mac);
ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_DISASSOCIATED, NULL);
spin_unlock_irqrestore(&mac->lock, flags);
}
@ -334,11 +334,19 @@ ieee80211softmac_associated(struct ieee80211softmac_device *mac,
struct ieee80211_assoc_response * resp,
struct ieee80211softmac_network *net)
{
u16 cap = le16_to_cpu(resp->capability);
u8 erp_value = net->erp_value;
mac->associnfo.associating = 0;
mac->associnfo.supported_rates = net->supported_rates;
mac->bssinfo.supported_rates = net->supported_rates;
ieee80211softmac_recalc_txrates(mac);
mac->associated = 1;
mac->associnfo.short_preamble_available =
(cap & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0;
ieee80211softmac_process_erp(mac, erp_value);
if (mac->set_bssid_filter)
mac->set_bssid_filter(mac->dev, net->bssid);
memcpy(mac->ieee->bssid, net->bssid, ETH_ALEN);
@ -351,9 +359,9 @@ ieee80211softmac_associated(struct ieee80211softmac_device *mac,
int
ieee80211softmac_handle_assoc_response(struct net_device * dev,
struct ieee80211_assoc_response * resp,
struct ieee80211_network * _ieee80211_network_do_not_use)
struct ieee80211_network * _ieee80211_network)
{
/* NOTE: the network parameter has to be ignored by
/* NOTE: the network parameter has to be mostly ignored by
* this code because it is the ieee80211's pointer
* to the struct, not ours (we made a copy)
*/
@ -385,6 +393,11 @@ ieee80211softmac_handle_assoc_response(struct net_device * dev,
/* now that we know it was for us, we can cancel the timeout */
cancel_delayed_work(&mac->associnfo.timeout);
/* if the association response included an ERP IE, update our saved
* copy */
if (_ieee80211_network->flags & NETWORK_HAS_ERP_VALUE)
network->erp_value = _ieee80211_network->erp_value;
switch (status) {
case 0:
dprintk(KERN_INFO PFX "associated!\n");

View file

@ -467,3 +467,17 @@ ieee80211softmac_send_mgt_frame(struct ieee80211softmac_device *mac,
kfree(pkt);
return 0;
}
/* Beacon handling */
int ieee80211softmac_handle_beacon(struct net_device *dev,
struct ieee80211_beacon *beacon,
struct ieee80211_network *network)
{
struct ieee80211softmac_device *mac = ieee80211_priv(dev);
if (mac->associated && memcmp(network->bssid, mac->associnfo.bssid, ETH_ALEN) == 0)
ieee80211softmac_process_erp(mac, network->erp_value);
return 0;
}

View file

@ -44,6 +44,7 @@ struct net_device *alloc_ieee80211softmac(int sizeof_priv)
softmac->ieee->handle_assoc_response = ieee80211softmac_handle_assoc_response;
softmac->ieee->handle_reassoc_request = ieee80211softmac_handle_reassoc_req;
softmac->ieee->handle_disassoc = ieee80211softmac_handle_disassoc;
softmac->ieee->handle_beacon = ieee80211softmac_handle_beacon;
softmac->scaninfo = NULL;
softmac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT;
@ -178,21 +179,14 @@ int ieee80211softmac_ratesinfo_rate_supported(struct ieee80211softmac_ratesinfo
return 0;
}
/* Finds the highest rate which is:
* 1. Present in ri (optionally a basic rate)
* 2. Supported by the device
* 3. Less than or equal to the user-defined rate
*/
static u8 highest_supported_rate(struct ieee80211softmac_device *mac,
u8 ieee80211softmac_highest_supported_rate(struct ieee80211softmac_device *mac,
struct ieee80211softmac_ratesinfo *ri, int basic_only)
{
u8 user_rate = mac->txrates.user_rate;
int i;
if (ri->count == 0) {
dprintk(KERN_ERR PFX "empty ratesinfo?\n");
if (ri->count == 0)
return IEEE80211_CCK_RATE_1MB;
}
for (i = ri->count - 1; i >= 0; i--) {
u8 rate = ri->rates[i];
@ -208,36 +202,61 @@ static u8 highest_supported_rate(struct ieee80211softmac_device *mac,
/* If we haven't found a suitable rate by now, just trust the user */
return user_rate;
}
EXPORT_SYMBOL_GPL(ieee80211softmac_highest_supported_rate);
void ieee80211softmac_process_erp(struct ieee80211softmac_device *mac,
u8 erp_value)
{
int use_protection;
int short_preamble;
u32 changes = 0;
/* Barker preamble mode */
short_preamble = ((erp_value & WLAN_ERP_BARKER_PREAMBLE) == 0
&& mac->associnfo.short_preamble_available) ? 1 : 0;
/* Protection needed? */
use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0;
if (mac->bssinfo.short_preamble != short_preamble) {
changes |= IEEE80211SOFTMAC_BSSINFOCHG_SHORT_PREAMBLE;
mac->bssinfo.short_preamble = short_preamble;
}
if (mac->bssinfo.use_protection != use_protection) {
changes |= IEEE80211SOFTMAC_BSSINFOCHG_PROTECTION;
mac->bssinfo.use_protection = use_protection;
}
if (mac->bssinfo_change && changes)
mac->bssinfo_change(mac->dev, changes);
}
void ieee80211softmac_recalc_txrates(struct ieee80211softmac_device *mac)
{
struct ieee80211softmac_txrates *txrates = &mac->txrates;
struct ieee80211softmac_txrates oldrates;
u32 change = 0;
if (mac->txrates_change)
oldrates = mac->txrates;
change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT;
txrates->default_rate = highest_supported_rate(mac, &mac->associnfo.supported_rates, 0);
txrates->default_rate = ieee80211softmac_highest_supported_rate(mac, &mac->bssinfo.supported_rates, 0);
change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK;
txrates->default_fallback = lower_rate(mac, txrates->default_rate);
change |= IEEE80211SOFTMAC_TXRATECHG_MCAST;
txrates->mcast_rate = highest_supported_rate(mac, &mac->associnfo.supported_rates, 1);
txrates->mcast_rate = ieee80211softmac_highest_supported_rate(mac, &mac->bssinfo.supported_rates, 1);
if (mac->txrates_change)
mac->txrates_change(mac->dev, change, &oldrates);
mac->txrates_change(mac->dev, change);
}
void ieee80211softmac_init_txrates(struct ieee80211softmac_device *mac)
void ieee80211softmac_init_bss(struct ieee80211softmac_device *mac)
{
struct ieee80211_device *ieee = mac->ieee;
u32 change = 0;
struct ieee80211softmac_txrates *txrates = &mac->txrates;
struct ieee80211softmac_txrates oldrates;
struct ieee80211softmac_bss_info *bssinfo = &mac->bssinfo;
/* TODO: We need some kind of state machine to lower the default rates
* if we loose too many packets.
@ -245,8 +264,6 @@ void ieee80211softmac_init_txrates(struct ieee80211softmac_device *mac)
/* Change the default txrate to the highest possible value.
* The txrate machine will lower it, if it is too high.
*/
if (mac->txrates_change)
oldrates = mac->txrates;
/* FIXME: We don't correctly handle backing down to lower
rates, so 801.11g devices start off at 11M for now. People
can manually change it if they really need to, but 11M is
@ -272,7 +289,23 @@ void ieee80211softmac_init_txrates(struct ieee80211softmac_device *mac)
change |= IEEE80211SOFTMAC_TXRATECHG_MGT_MCAST;
if (mac->txrates_change)
mac->txrates_change(mac->dev, change, &oldrates);
mac->txrates_change(mac->dev, change);
change = 0;
bssinfo->supported_rates.count = 0;
memset(bssinfo->supported_rates.rates, 0,
sizeof(bssinfo->supported_rates.rates));
change |= IEEE80211SOFTMAC_BSSINFOCHG_RATES;
bssinfo->short_preamble = 0;
change |= IEEE80211SOFTMAC_BSSINFOCHG_SHORT_PREAMBLE;
bssinfo->use_protection = 0;
change |= IEEE80211SOFTMAC_BSSINFOCHG_PROTECTION;
if (mac->bssinfo_change)
mac->bssinfo_change(mac->dev, change);
mac->running = 1;
}
@ -282,7 +315,7 @@ void ieee80211softmac_start(struct net_device *dev)
struct ieee80211softmac_device *mac = ieee80211_priv(dev);
ieee80211softmac_start_check_rates(mac);
ieee80211softmac_init_txrates(mac);
ieee80211softmac_init_bss(mac);
}
EXPORT_SYMBOL_GPL(ieee80211softmac_start);
@ -335,7 +368,6 @@ u8 ieee80211softmac_lower_rate_delta(struct ieee80211softmac_device *mac, u8 rat
static void ieee80211softmac_add_txrates_badness(struct ieee80211softmac_device *mac,
int amount)
{
struct ieee80211softmac_txrates oldrates;
u8 default_rate = mac->txrates.default_rate;
u8 default_fallback = mac->txrates.default_fallback;
u32 changes = 0;
@ -348,8 +380,6 @@ printk("badness %d\n", mac->txrate_badness);
mac->txrate_badness += amount;
if (mac->txrate_badness <= -1000) {
/* Very small badness. Try a faster bitrate. */
if (mac->txrates_change)
memcpy(&oldrates, &mac->txrates, sizeof(oldrates));
default_rate = raise_rate(mac, default_rate);
changes |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT;
default_fallback = get_fallback_rate(mac, default_rate);
@ -358,8 +388,6 @@ printk("badness %d\n", mac->txrate_badness);
printk("Bitrate raised to %u\n", default_rate);
} else if (mac->txrate_badness >= 10000) {
/* Very high badness. Try a slower bitrate. */
if (mac->txrates_change)
memcpy(&oldrates, &mac->txrates, sizeof(oldrates));
default_rate = lower_rate(mac, default_rate);
changes |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT;
default_fallback = get_fallback_rate(mac, default_rate);
@ -372,7 +400,7 @@ printk("Bitrate lowered to %u\n", default_rate);
mac->txrates.default_fallback = default_fallback;
if (changes && mac->txrates_change)
mac->txrates_change(mac->dev, changes, &oldrates);
mac->txrates_change(mac->dev, changes);
}
void ieee80211softmac_fragment_lost(struct net_device *dev,
@ -416,7 +444,11 @@ ieee80211softmac_create_network(struct ieee80211softmac_device *mac,
memcpy(&softnet->supported_rates.rates[softnet->supported_rates.count], net->rates_ex, net->rates_ex_len);
softnet->supported_rates.count += net->rates_ex_len;
sort(softnet->supported_rates.rates, softnet->supported_rates.count, sizeof(softnet->supported_rates.rates[0]), rate_cmp, NULL);
/* we save the ERP value because it is needed at association time, and
* many AP's do not include an ERP IE in the association response. */
softnet->erp_value = net->erp_value;
softnet->capabilities = net->capability;
return softnet;
}

View file

@ -116,9 +116,11 @@ ieee80211softmac_get_network_by_essid(struct ieee80211softmac_device *mac,
struct ieee80211softmac_essid *essid);
/* Rates related */
void ieee80211softmac_process_erp(struct ieee80211softmac_device *mac,
u8 erp_value);
int ieee80211softmac_ratesinfo_rate_supported(struct ieee80211softmac_ratesinfo *ri, u8 rate);
u8 ieee80211softmac_lower_rate_delta(struct ieee80211softmac_device *mac, u8 rate, int delta);
void ieee80211softmac_init_txrates(struct ieee80211softmac_device *mac);
void ieee80211softmac_init_bss(struct ieee80211softmac_device *mac);
void ieee80211softmac_recalc_txrates(struct ieee80211softmac_device *mac);
static inline u8 lower_rate(struct ieee80211softmac_device *mac, u8 rate) {
return ieee80211softmac_lower_rate_delta(mac, rate, 1);
@ -133,6 +135,9 @@ static inline u8 get_fallback_rate(struct ieee80211softmac_device *mac, u8 rate)
/*** prototypes from _io.c */
int ieee80211softmac_send_mgt_frame(struct ieee80211softmac_device *mac,
void* ptrarg, u32 type, u32 arg);
int ieee80211softmac_handle_beacon(struct net_device *dev,
struct ieee80211_beacon *beacon,
struct ieee80211_network *network);
/*** prototypes from _auth.c */
/* do these have to go into the public header? */
@ -189,6 +194,7 @@ struct ieee80211softmac_network {
authenticated:1,
auth_desynced_once:1;
u8 erp_value; /* Saved ERP value */
u16 capabilities; /* Capabilities bitfield */
u8 challenge_len; /* Auth Challenge length */
char *challenge; /* Challenge Text */