提交 b0df3bd1 编写于 作者: J Jeff Garzik

Merge branch 'upstream' of...

Merge branch 'upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6 into tmp
...@@ -2655,7 +2655,6 @@ M: josejx@gentoo.org ...@@ -2655,7 +2655,6 @@ M: josejx@gentoo.org
P: Daniel Drake P: Daniel Drake
M: dsd@gentoo.org M: dsd@gentoo.org
W: http://softmac.sipsolutions.net/ W: http://softmac.sipsolutions.net/
L: softmac-dev@sipsolutions.net
L: netdev@vger.kernel.org L: netdev@vger.kernel.org
S: Maintained S: Maintained
......
...@@ -5868,7 +5868,7 @@ static int airo_set_essid(struct net_device *dev, ...@@ -5868,7 +5868,7 @@ static int airo_set_essid(struct net_device *dev,
int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
/* Check the size of the string */ /* Check the size of the string */
if(dwrq->length > IW_ESSID_MAX_SIZE+1) { if(dwrq->length > IW_ESSID_MAX_SIZE) {
return -E2BIG ; return -E2BIG ;
} }
/* Check if index is valid */ /* Check if index is valid */
...@@ -5880,7 +5880,7 @@ static int airo_set_essid(struct net_device *dev, ...@@ -5880,7 +5880,7 @@ static int airo_set_essid(struct net_device *dev,
memset(SSID_rid.ssids[index].ssid, 0, memset(SSID_rid.ssids[index].ssid, 0,
sizeof(SSID_rid.ssids[index].ssid)); sizeof(SSID_rid.ssids[index].ssid));
memcpy(SSID_rid.ssids[index].ssid, extra, dwrq->length); memcpy(SSID_rid.ssids[index].ssid, extra, dwrq->length);
SSID_rid.ssids[index].len = dwrq->length - 1; SSID_rid.ssids[index].len = dwrq->length;
} }
SSID_rid.len = sizeof(SSID_rid); SSID_rid.len = sizeof(SSID_rid);
/* Write it to the card */ /* Write it to the card */
...@@ -5990,7 +5990,7 @@ static int airo_set_nick(struct net_device *dev, ...@@ -5990,7 +5990,7 @@ static int airo_set_nick(struct net_device *dev,
struct airo_info *local = dev->priv; struct airo_info *local = dev->priv;
/* Check the size of the string */ /* Check the size of the string */
if(dwrq->length > 16 + 1) { if(dwrq->length > 16) {
return -E2BIG; return -E2BIG;
} }
readConfigRid(local, 1); readConfigRid(local, 1);
...@@ -6015,7 +6015,7 @@ static int airo_get_nick(struct net_device *dev, ...@@ -6015,7 +6015,7 @@ static int airo_get_nick(struct net_device *dev,
readConfigRid(local, 1); readConfigRid(local, 1);
strncpy(extra, local->config.nodeName, 16); strncpy(extra, local->config.nodeName, 16);
extra[16] = '\0'; extra[16] = '\0';
dwrq->length = strlen(extra) + 1; dwrq->length = strlen(extra);
return 0; return 0;
} }
...@@ -6767,9 +6767,9 @@ static int airo_set_retry(struct net_device *dev, ...@@ -6767,9 +6767,9 @@ static int airo_set_retry(struct net_device *dev,
} }
readConfigRid(local, 1); readConfigRid(local, 1);
if(vwrq->flags & IW_RETRY_LIMIT) { if(vwrq->flags & IW_RETRY_LIMIT) {
if(vwrq->flags & IW_RETRY_MAX) if(vwrq->flags & IW_RETRY_LONG)
local->config.longRetryLimit = vwrq->value; local->config.longRetryLimit = vwrq->value;
else if (vwrq->flags & IW_RETRY_MIN) else if (vwrq->flags & IW_RETRY_SHORT)
local->config.shortRetryLimit = vwrq->value; local->config.shortRetryLimit = vwrq->value;
else { else {
/* No modifier : set both */ /* No modifier : set both */
...@@ -6805,14 +6805,14 @@ static int airo_get_retry(struct net_device *dev, ...@@ -6805,14 +6805,14 @@ static int airo_get_retry(struct net_device *dev,
if((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) { if((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
vwrq->flags = IW_RETRY_LIFETIME; vwrq->flags = IW_RETRY_LIFETIME;
vwrq->value = (int)local->config.txLifetime * 1024; vwrq->value = (int)local->config.txLifetime * 1024;
} else if((vwrq->flags & IW_RETRY_MAX)) { } else if((vwrq->flags & IW_RETRY_LONG)) {
vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
vwrq->value = (int)local->config.longRetryLimit; vwrq->value = (int)local->config.longRetryLimit;
} else { } else {
vwrq->flags = IW_RETRY_LIMIT; vwrq->flags = IW_RETRY_LIMIT;
vwrq->value = (int)local->config.shortRetryLimit; vwrq->value = (int)local->config.shortRetryLimit;
if((int)local->config.shortRetryLimit != (int)local->config.longRetryLimit) if((int)local->config.shortRetryLimit != (int)local->config.longRetryLimit)
vwrq->flags |= IW_RETRY_MIN; vwrq->flags |= IW_RETRY_SHORT;
} }
return 0; return 0;
...@@ -6990,6 +6990,7 @@ static int airo_set_power(struct net_device *dev, ...@@ -6990,6 +6990,7 @@ static int airo_set_power(struct net_device *dev,
local->config.rmode |= RXMODE_BC_MC_ADDR; local->config.rmode |= RXMODE_BC_MC_ADDR;
set_bit (FLAG_COMMIT, &local->flags); set_bit (FLAG_COMMIT, &local->flags);
case IW_POWER_ON: case IW_POWER_ON:
/* This is broken, fixme ;-) */
break; break;
default: default:
return -EINVAL; return -EINVAL;
......
...@@ -1656,13 +1656,13 @@ static int atmel_set_essid(struct net_device *dev, ...@@ -1656,13 +1656,13 @@ static int atmel_set_essid(struct net_device *dev,
priv->connect_to_any_BSS = 0; priv->connect_to_any_BSS = 0;
/* Check the size of the string */ /* Check the size of the string */
if (dwrq->length > MAX_SSID_LENGTH + 1) if (dwrq->length > MAX_SSID_LENGTH)
return -E2BIG; return -E2BIG;
if (index != 0) if (index != 0)
return -EINVAL; return -EINVAL;
memcpy(priv->new_SSID, extra, dwrq->length - 1); memcpy(priv->new_SSID, extra, dwrq->length);
priv->new_SSID_size = dwrq->length - 1; priv->new_SSID_size = dwrq->length;
} }
return -EINPROGRESS; return -EINPROGRESS;
...@@ -2120,9 +2120,9 @@ static int atmel_set_retry(struct net_device *dev, ...@@ -2120,9 +2120,9 @@ static int atmel_set_retry(struct net_device *dev,
struct atmel_private *priv = netdev_priv(dev); struct atmel_private *priv = netdev_priv(dev);
if (!vwrq->disabled && (vwrq->flags & IW_RETRY_LIMIT)) { if (!vwrq->disabled && (vwrq->flags & IW_RETRY_LIMIT)) {
if (vwrq->flags & IW_RETRY_MAX) if (vwrq->flags & IW_RETRY_LONG)
priv->long_retry = vwrq->value; priv->long_retry = vwrq->value;
else if (vwrq->flags & IW_RETRY_MIN) else if (vwrq->flags & IW_RETRY_SHORT)
priv->short_retry = vwrq->value; priv->short_retry = vwrq->value;
else { else {
/* No modifier : set both */ /* No modifier : set both */
...@@ -2144,15 +2144,15 @@ static int atmel_get_retry(struct net_device *dev, ...@@ -2144,15 +2144,15 @@ static int atmel_get_retry(struct net_device *dev,
vwrq->disabled = 0; /* Can't be disabled */ vwrq->disabled = 0; /* Can't be disabled */
/* Note : by default, display the min retry number */ /* Note : by default, display the short retry number */
if (vwrq->flags & IW_RETRY_MAX) { if (vwrq->flags & IW_RETRY_LONG) {
vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
vwrq->value = priv->long_retry; vwrq->value = priv->long_retry;
} else { } else {
vwrq->flags = IW_RETRY_LIMIT; vwrq->flags = IW_RETRY_LIMIT;
vwrq->value = priv->short_retry; vwrq->value = priv->short_retry;
if (priv->long_retry != priv->short_retry) if (priv->long_retry != priv->short_retry)
vwrq->flags |= IW_RETRY_MIN; vwrq->flags |= IW_RETRY_SHORT;
} }
return 0; return 0;
......
...@@ -666,7 +666,6 @@ struct bcm43xx_noise_calculation { ...@@ -666,7 +666,6 @@ struct bcm43xx_noise_calculation {
}; };
struct bcm43xx_stats { struct bcm43xx_stats {
u8 link_quality;
u8 noise; u8 noise;
struct iw_statistics wstats; struct iw_statistics wstats;
/* Store the last TX/RX times here for updating the leds. */ /* Store the last TX/RX times here for updating the leds. */
......
...@@ -2405,9 +2405,10 @@ static int bcm43xx_chip_init(struct bcm43xx_private *bcm) ...@@ -2405,9 +2405,10 @@ static int bcm43xx_chip_init(struct bcm43xx_private *bcm)
BCM43xx_UCODE_TIME) & 0x1f); BCM43xx_UCODE_TIME) & 0x1f);
if ( value16 > 0x128 ) { if ( value16 > 0x128 ) {
dprintk(KERN_ERR PFX printk(KERN_ERR PFX
"Firmware: no support for microcode rev > 0x128\n"); "Firmware: no support for microcode extracted "
err = -1; "from version 4.x binary drivers.\n");
err = -EOPNOTSUPP;
goto err_release_fw; goto err_release_fw;
} }
...@@ -3169,8 +3170,7 @@ static void bcm43xx_periodic_work_handler(void *d) ...@@ -3169,8 +3170,7 @@ static void bcm43xx_periodic_work_handler(void *d)
* be preemtible. * be preemtible.
*/ */
mutex_lock(&bcm->mutex); mutex_lock(&bcm->mutex);
netif_stop_queue(bcm->net_dev); netif_tx_disable(bcm->net_dev);
synchronize_net();
spin_lock_irqsave(&bcm->irq_lock, flags); spin_lock_irqsave(&bcm->irq_lock, flags);
bcm43xx_mac_suspend(bcm); bcm43xx_mac_suspend(bcm);
if (bcm43xx_using_pio(bcm)) if (bcm43xx_using_pio(bcm))
......
...@@ -361,7 +361,7 @@ static void bcm43xx_phy_setupg(struct bcm43xx_private *bcm) ...@@ -361,7 +361,7 @@ static void bcm43xx_phy_setupg(struct bcm43xx_private *bcm)
if (phy->rev <= 2) if (phy->rev <= 2)
for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++) for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++)
bcm43xx_ilt_write(bcm, 0x1400 + i, bcm43xx_ilt_noisescaleg1[i]); bcm43xx_ilt_write(bcm, 0x1400 + i, bcm43xx_ilt_noisescaleg1[i]);
else if ((phy->rev == 7) && (bcm43xx_phy_read(bcm, 0x0449) & 0x0200)) else if ((phy->rev >= 7) && (bcm43xx_phy_read(bcm, 0x0449) & 0x0200))
for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++) for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++)
bcm43xx_ilt_write(bcm, 0x1400 + i, bcm43xx_ilt_noisescaleg3[i]); bcm43xx_ilt_write(bcm, 0x1400 + i, bcm43xx_ilt_noisescaleg3[i]);
else else
...@@ -371,7 +371,7 @@ static void bcm43xx_phy_setupg(struct bcm43xx_private *bcm) ...@@ -371,7 +371,7 @@ static void bcm43xx_phy_setupg(struct bcm43xx_private *bcm)
if (phy->rev == 2) if (phy->rev == 2)
for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++) for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++)
bcm43xx_ilt_write(bcm, 0x5000 + i, bcm43xx_ilt_sigmasqr1[i]); bcm43xx_ilt_write(bcm, 0x5000 + i, bcm43xx_ilt_sigmasqr1[i]);
else if ((phy->rev > 2) && (phy->rev <= 7)) else if ((phy->rev > 2) && (phy->rev <= 8))
for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++) for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++)
bcm43xx_ilt_write(bcm, 0x5000 + i, bcm43xx_ilt_sigmasqr2[i]); bcm43xx_ilt_write(bcm, 0x5000 + i, bcm43xx_ilt_sigmasqr2[i]);
...@@ -1197,7 +1197,7 @@ static void bcm43xx_phy_initg(struct bcm43xx_private *bcm) ...@@ -1197,7 +1197,7 @@ static void bcm43xx_phy_initg(struct bcm43xx_private *bcm)
if (phy->rev == 1) if (phy->rev == 1)
bcm43xx_phy_initb5(bcm); bcm43xx_phy_initb5(bcm);
else if (phy->rev >= 2 && phy->rev <= 7) else
bcm43xx_phy_initb6(bcm); bcm43xx_phy_initb6(bcm);
if (phy->rev >= 2 || phy->connected) if (phy->rev >= 2 || phy->connected)
bcm43xx_phy_inita(bcm); bcm43xx_phy_inita(bcm);
...@@ -1241,23 +1241,22 @@ static void bcm43xx_phy_initg(struct bcm43xx_private *bcm) ...@@ -1241,23 +1241,22 @@ static void bcm43xx_phy_initg(struct bcm43xx_private *bcm)
bcm43xx_phy_lo_g_measure(bcm); bcm43xx_phy_lo_g_measure(bcm);
} else { } else {
if (radio->version == 0x2050 && radio->revision == 8) { if (radio->version == 0x2050 && radio->revision == 8) {
//FIXME bcm43xx_radio_write16(bcm, 0x0052,
(radio->txctl1 << 4) | radio->txctl2);
} else { } else {
bcm43xx_radio_write16(bcm, 0x0052, bcm43xx_radio_write16(bcm, 0x0052,
(bcm43xx_radio_read16(bcm, 0x0052) (bcm43xx_radio_read16(bcm, 0x0052)
& 0xFFF0) | radio->txctl1); & 0xFFF0) | radio->txctl1);
} }
if (phy->rev >= 6) { if (phy->rev >= 6) {
/*
bcm43xx_phy_write(bcm, 0x0036, bcm43xx_phy_write(bcm, 0x0036,
(bcm43xx_phy_read(bcm, 0x0036) (bcm43xx_phy_read(bcm, 0x0036)
& 0xF000) | (FIXME << 12)); & 0xF000) | (radio->txctl2 << 12));
*/
} }
if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL) if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL)
bcm43xx_phy_write(bcm, 0x002E, 0x8075); bcm43xx_phy_write(bcm, 0x002E, 0x8075);
else else
bcm43xx_phy_write(bcm, 0x003E, 0x807F); bcm43xx_phy_write(bcm, 0x002E, 0x807F);
if (phy->rev < 2) if (phy->rev < 2)
bcm43xx_phy_write(bcm, 0x002F, 0x0101); bcm43xx_phy_write(bcm, 0x002F, 0x0101);
else else
......
...@@ -334,7 +334,7 @@ static int bcm43xx_wx_get_nick(struct net_device *net_dev, ...@@ -334,7 +334,7 @@ static int bcm43xx_wx_get_nick(struct net_device *net_dev,
size_t len; size_t len;
mutex_lock(&bcm->mutex); mutex_lock(&bcm->mutex);
len = strlen(bcm->nick) + 1; len = strlen(bcm->nick);
memcpy(extra, bcm->nick, len); memcpy(extra, bcm->nick, len);
data->data.length = (__u16)len; data->data.length = (__u16)len;
data->data.flags = 1; data->data.flags = 1;
......
...@@ -496,15 +496,14 @@ int bcm43xx_rx(struct bcm43xx_private *bcm, ...@@ -496,15 +496,14 @@ int bcm43xx_rx(struct bcm43xx_private *bcm,
stats.signal = bcm43xx_rssi_postprocess(bcm, rxhdr->rssi, is_ofdm, stats.signal = bcm43xx_rssi_postprocess(bcm, rxhdr->rssi, is_ofdm,
!!(rxflags1 & BCM43xx_RXHDR_FLAGS1_2053RSSIADJ), !!(rxflags1 & BCM43xx_RXHDR_FLAGS1_2053RSSIADJ),
!!(rxflags3 & BCM43xx_RXHDR_FLAGS3_2050RSSIADJ)); !!(rxflags3 & BCM43xx_RXHDR_FLAGS3_2050RSSIADJ));
//TODO stats.noise = stats.noise = bcm->stats.noise;
if (is_ofdm) if (is_ofdm)
stats.rate = bcm43xx_plcp_get_bitrate_ofdm(plcp); stats.rate = bcm43xx_plcp_get_bitrate_ofdm(plcp);
else else
stats.rate = bcm43xx_plcp_get_bitrate_cck(plcp); stats.rate = bcm43xx_plcp_get_bitrate_cck(plcp);
stats.received_channel = radio->channel; stats.received_channel = radio->channel;
//TODO stats.control =
stats.mask = IEEE80211_STATMASK_SIGNAL | stats.mask = IEEE80211_STATMASK_SIGNAL |
//TODO IEEE80211_STATMASK_NOISE | IEEE80211_STATMASK_NOISE |
IEEE80211_STATMASK_RATE | IEEE80211_STATMASK_RATE |
IEEE80211_STATMASK_RSSI; IEEE80211_STATMASK_RSSI;
if (phy->type == BCM43xx_PHYTYPE_A) if (phy->type == BCM43xx_PHYTYPE_A)
......
...@@ -1412,9 +1412,9 @@ static int prism2_ioctl_siwretry(struct net_device *dev, ...@@ -1412,9 +1412,9 @@ static int prism2_ioctl_siwretry(struct net_device *dev,
/* what could be done, if firmware would support this.. */ /* what could be done, if firmware would support this.. */
if (rrq->flags & IW_RETRY_LIMIT) { if (rrq->flags & IW_RETRY_LIMIT) {
if (rrq->flags & IW_RETRY_MAX) if (rrq->flags & IW_RETRY_LONG)
HFA384X_RID_LONGRETRYLIMIT = rrq->value; HFA384X_RID_LONGRETRYLIMIT = rrq->value;
else if (rrq->flags & IW_RETRY_MIN) else if (rrq->flags & IW_RETRY_SHORT)
HFA384X_RID_SHORTRETRYLIMIT = rrq->value; HFA384X_RID_SHORTRETRYLIMIT = rrq->value;
else { else {
HFA384X_RID_LONGRETRYLIMIT = rrq->value; HFA384X_RID_LONGRETRYLIMIT = rrq->value;
...@@ -1468,14 +1468,14 @@ static int prism2_ioctl_giwretry(struct net_device *dev, ...@@ -1468,14 +1468,14 @@ static int prism2_ioctl_giwretry(struct net_device *dev,
rrq->value = le16_to_cpu(altretry); rrq->value = le16_to_cpu(altretry);
else else
rrq->value = local->manual_retry_count; rrq->value = local->manual_retry_count;
} else if ((rrq->flags & IW_RETRY_MAX)) { } else if ((rrq->flags & IW_RETRY_LONG)) {
rrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
rrq->value = longretry; rrq->value = longretry;
} else { } else {
rrq->flags = IW_RETRY_LIMIT; rrq->flags = IW_RETRY_LIMIT;
rrq->value = shortretry; rrq->value = shortretry;
if (shortretry != longretry) if (shortretry != longretry)
rrq->flags |= IW_RETRY_MIN; rrq->flags |= IW_RETRY_SHORT;
} }
} }
return 0; return 0;
......
...@@ -6958,7 +6958,7 @@ static int ipw2100_wx_set_essid(struct net_device *dev, ...@@ -6958,7 +6958,7 @@ static int ipw2100_wx_set_essid(struct net_device *dev,
} }
if (wrqu->essid.flags && wrqu->essid.length) { if (wrqu->essid.flags && wrqu->essid.length) {
length = wrqu->essid.length - 1; length = wrqu->essid.length;
essid = extra; essid = extra;
} }
...@@ -7051,7 +7051,7 @@ static int ipw2100_wx_get_nick(struct net_device *dev, ...@@ -7051,7 +7051,7 @@ static int ipw2100_wx_get_nick(struct net_device *dev,
struct ipw2100_priv *priv = ieee80211_priv(dev); struct ipw2100_priv *priv = ieee80211_priv(dev);
wrqu->data.length = strlen(priv->nick) + 1; wrqu->data.length = strlen(priv->nick);
memcpy(extra, priv->nick, wrqu->data.length); memcpy(extra, priv->nick, wrqu->data.length);
wrqu->data.flags = 1; /* active */ wrqu->data.flags = 1; /* active */
...@@ -7343,14 +7343,14 @@ static int ipw2100_wx_set_retry(struct net_device *dev, ...@@ -7343,14 +7343,14 @@ static int ipw2100_wx_set_retry(struct net_device *dev,
goto done; goto done;
} }
if (wrqu->retry.flags & IW_RETRY_MIN) { if (wrqu->retry.flags & IW_RETRY_SHORT) {
err = ipw2100_set_short_retry(priv, wrqu->retry.value); err = ipw2100_set_short_retry(priv, wrqu->retry.value);
IPW_DEBUG_WX("SET Short Retry Limit -> %d \n", IPW_DEBUG_WX("SET Short Retry Limit -> %d \n",
wrqu->retry.value); wrqu->retry.value);
goto done; goto done;
} }
if (wrqu->retry.flags & IW_RETRY_MAX) { if (wrqu->retry.flags & IW_RETRY_LONG) {
err = ipw2100_set_long_retry(priv, wrqu->retry.value); err = ipw2100_set_long_retry(priv, wrqu->retry.value);
IPW_DEBUG_WX("SET Long Retry Limit -> %d \n", IPW_DEBUG_WX("SET Long Retry Limit -> %d \n",
wrqu->retry.value); wrqu->retry.value);
...@@ -7383,14 +7383,14 @@ static int ipw2100_wx_get_retry(struct net_device *dev, ...@@ -7383,14 +7383,14 @@ static int ipw2100_wx_get_retry(struct net_device *dev,
if ((wrqu->retry.flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) if ((wrqu->retry.flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME)
return -EINVAL; return -EINVAL;
if (wrqu->retry.flags & IW_RETRY_MAX) { if (wrqu->retry.flags & IW_RETRY_LONG) {
wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX; wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
wrqu->retry.value = priv->long_retry_limit; wrqu->retry.value = priv->long_retry_limit;
} else { } else {
wrqu->retry.flags = wrqu->retry.flags =
(priv->short_retry_limit != (priv->short_retry_limit !=
priv->long_retry_limit) ? priv->long_retry_limit) ?
IW_RETRY_LIMIT | IW_RETRY_MIN : IW_RETRY_LIMIT; IW_RETRY_LIMIT | IW_RETRY_SHORT : IW_RETRY_LIMIT;
wrqu->retry.value = priv->short_retry_limit; wrqu->retry.value = priv->short_retry_limit;
} }
......
...@@ -8875,8 +8875,6 @@ static int ipw_wx_set_essid(struct net_device *dev, ...@@ -8875,8 +8875,6 @@ static int ipw_wx_set_essid(struct net_device *dev,
} }
length = min((int)wrqu->essid.length, IW_ESSID_MAX_SIZE); length = min((int)wrqu->essid.length, IW_ESSID_MAX_SIZE);
if (!extra[length - 1])
length--;
priv->config |= CFG_STATIC_ESSID; priv->config |= CFG_STATIC_ESSID;
...@@ -8953,7 +8951,7 @@ static int ipw_wx_get_nick(struct net_device *dev, ...@@ -8953,7 +8951,7 @@ static int ipw_wx_get_nick(struct net_device *dev,
struct ipw_priv *priv = ieee80211_priv(dev); struct ipw_priv *priv = ieee80211_priv(dev);
IPW_DEBUG_WX("Getting nick\n"); IPW_DEBUG_WX("Getting nick\n");
mutex_lock(&priv->mutex); mutex_lock(&priv->mutex);
wrqu->data.length = strlen(priv->nick) + 1; wrqu->data.length = strlen(priv->nick);
memcpy(extra, priv->nick, wrqu->data.length); memcpy(extra, priv->nick, wrqu->data.length);
wrqu->data.flags = 1; /* active */ wrqu->data.flags = 1; /* active */
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);
...@@ -9276,9 +9274,9 @@ static int ipw_wx_set_retry(struct net_device *dev, ...@@ -9276,9 +9274,9 @@ static int ipw_wx_set_retry(struct net_device *dev,
return -EINVAL; return -EINVAL;
mutex_lock(&priv->mutex); mutex_lock(&priv->mutex);
if (wrqu->retry.flags & IW_RETRY_MIN) if (wrqu->retry.flags & IW_RETRY_SHORT)
priv->short_retry_limit = (u8) wrqu->retry.value; priv->short_retry_limit = (u8) wrqu->retry.value;
else if (wrqu->retry.flags & IW_RETRY_MAX) else if (wrqu->retry.flags & IW_RETRY_LONG)
priv->long_retry_limit = (u8) wrqu->retry.value; priv->long_retry_limit = (u8) wrqu->retry.value;
else { else {
priv->short_retry_limit = (u8) wrqu->retry.value; priv->short_retry_limit = (u8) wrqu->retry.value;
...@@ -9307,11 +9305,11 @@ static int ipw_wx_get_retry(struct net_device *dev, ...@@ -9307,11 +9305,11 @@ static int ipw_wx_get_retry(struct net_device *dev,
return -EINVAL; return -EINVAL;
} }
if (wrqu->retry.flags & IW_RETRY_MAX) { if (wrqu->retry.flags & IW_RETRY_LONG) {
wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX; wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
wrqu->retry.value = priv->long_retry_limit; wrqu->retry.value = priv->long_retry_limit;
} else if (wrqu->retry.flags & IW_RETRY_MIN) { } else if (wrqu->retry.flags & IW_RETRY_SHORT) {
wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN; wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_SHORT;
wrqu->retry.value = priv->short_retry_limit; wrqu->retry.value = priv->short_retry_limit;
} else { } else {
wrqu->retry.flags = IW_RETRY_LIMIT; wrqu->retry.flags = IW_RETRY_LIMIT;
......
...@@ -3037,7 +3037,7 @@ static int orinoco_ioctl_getessid(struct net_device *dev, ...@@ -3037,7 +3037,7 @@ static int orinoco_ioctl_getessid(struct net_device *dev,
} }
erq->flags = 1; erq->flags = 1;
erq->length = strlen(essidbuf) + 1; erq->length = strlen(essidbuf);
return 0; return 0;
} }
...@@ -3078,7 +3078,7 @@ static int orinoco_ioctl_getnick(struct net_device *dev, ...@@ -3078,7 +3078,7 @@ static int orinoco_ioctl_getnick(struct net_device *dev,
memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE+1); memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE+1);
orinoco_unlock(priv, &flags); orinoco_unlock(priv, &flags);
nrq->length = strlen(nickbuf)+1; nrq->length = strlen(nickbuf);
return 0; return 0;
} }
...@@ -3575,14 +3575,14 @@ static int orinoco_ioctl_getretry(struct net_device *dev, ...@@ -3575,14 +3575,14 @@ static int orinoco_ioctl_getretry(struct net_device *dev,
rrq->value = lifetime * 1000; /* ??? */ rrq->value = lifetime * 1000; /* ??? */
} else { } else {
/* By default, display the min number */ /* By default, display the min number */
if ((rrq->flags & IW_RETRY_MAX)) { if ((rrq->flags & IW_RETRY_LONG)) {
rrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
rrq->value = long_limit; rrq->value = long_limit;
} else { } else {
rrq->flags = IW_RETRY_LIMIT; rrq->flags = IW_RETRY_LIMIT;
rrq->value = short_limit; rrq->value = short_limit;
if(short_limit != long_limit) if(short_limit != long_limit)
rrq->flags |= IW_RETRY_MIN; rrq->flags |= IW_RETRY_SHORT;
} }
} }
......
...@@ -742,9 +742,9 @@ prism54_set_essid(struct net_device *ndev, struct iw_request_info *info, ...@@ -742,9 +742,9 @@ prism54_set_essid(struct net_device *ndev, struct iw_request_info *info,
/* Check if we were asked for `any' */ /* Check if we were asked for `any' */
if (dwrq->flags && dwrq->length) { if (dwrq->flags && dwrq->length) {
if (dwrq->length > min(33, IW_ESSID_MAX_SIZE + 1)) if (dwrq->length > 32)
return -E2BIG; return -E2BIG;
essid.length = dwrq->length - 1; essid.length = dwrq->length;
memcpy(essid.octets, extra, dwrq->length); memcpy(essid.octets, extra, dwrq->length);
} else } else
essid.length = 0; essid.length = 0;
...@@ -814,7 +814,7 @@ prism54_get_nick(struct net_device *ndev, struct iw_request_info *info, ...@@ -814,7 +814,7 @@ prism54_get_nick(struct net_device *ndev, struct iw_request_info *info,
dwrq->length = 0; dwrq->length = 0;
down_read(&priv->mib_sem); down_read(&priv->mib_sem);
dwrq->length = strlen(priv->nickname) + 1; dwrq->length = strlen(priv->nickname);
memcpy(extra, priv->nickname, dwrq->length); memcpy(extra, priv->nickname, dwrq->length);
up_read(&priv->mib_sem); up_read(&priv->mib_sem);
...@@ -992,9 +992,9 @@ prism54_set_retry(struct net_device *ndev, struct iw_request_info *info, ...@@ -992,9 +992,9 @@ prism54_set_retry(struct net_device *ndev, struct iw_request_info *info,
return -EINVAL; return -EINVAL;
if (vwrq->flags & IW_RETRY_LIMIT) { if (vwrq->flags & IW_RETRY_LIMIT) {
if (vwrq->flags & IW_RETRY_MIN) if (vwrq->flags & IW_RETRY_SHORT)
slimit = vwrq->value; slimit = vwrq->value;
else if (vwrq->flags & IW_RETRY_MAX) else if (vwrq->flags & IW_RETRY_LONG)
llimit = vwrq->value; llimit = vwrq->value;
else { else {
/* we are asked to set both */ /* we are asked to set both */
...@@ -1035,18 +1035,18 @@ prism54_get_retry(struct net_device *ndev, struct iw_request_info *info, ...@@ -1035,18 +1035,18 @@ prism54_get_retry(struct net_device *ndev, struct iw_request_info *info,
mgt_get_request(priv, DOT11_OID_MAXTXLIFETIME, 0, NULL, &r); mgt_get_request(priv, DOT11_OID_MAXTXLIFETIME, 0, NULL, &r);
vwrq->value = r.u * 1024; vwrq->value = r.u * 1024;
vwrq->flags = IW_RETRY_LIFETIME; vwrq->flags = IW_RETRY_LIFETIME;
} else if ((vwrq->flags & IW_RETRY_MAX)) { } else if ((vwrq->flags & IW_RETRY_LONG)) {
/* we are asked for the long retry limit */ /* we are asked for the long retry limit */
rvalue |= rvalue |=
mgt_get_request(priv, DOT11_OID_LONGRETRIES, 0, NULL, &r); mgt_get_request(priv, DOT11_OID_LONGRETRIES, 0, NULL, &r);
vwrq->value = r.u; vwrq->value = r.u;
vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
} else { } else {
/* default. get the short retry limit */ /* default. get the short retry limit */
rvalue |= rvalue |=
mgt_get_request(priv, DOT11_OID_SHORTRETRIES, 0, NULL, &r); mgt_get_request(priv, DOT11_OID_SHORTRETRIES, 0, NULL, &r);
vwrq->value = r.u; vwrq->value = r.u;
vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MIN; vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_SHORT;
} }
return rvalue; return rvalue;
......
...@@ -1173,7 +1173,7 @@ static int ray_set_essid(struct net_device *dev, ...@@ -1173,7 +1173,7 @@ static int ray_set_essid(struct net_device *dev,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} else { } else {
/* Check the size of the string */ /* Check the size of the string */
if(dwrq->length > IW_ESSID_MAX_SIZE + 1) { if(dwrq->length > IW_ESSID_MAX_SIZE) {
return -E2BIG; return -E2BIG;
} }
......
...@@ -1802,15 +1802,15 @@ static int wl3501_get_retry(struct net_device *dev, ...@@ -1802,15 +1802,15 @@ static int wl3501_get_retry(struct net_device *dev,
&retry, sizeof(retry)); &retry, sizeof(retry));
if (rc) if (rc)
goto out; goto out;
if (wrqu->retry.flags & IW_RETRY_MAX) { if (wrqu->retry.flags & IW_RETRY_LONG) {
wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX; wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
goto set_value; goto set_value;
} }
rc = wl3501_get_mib_value(this, WL3501_MIB_ATTR_SHORT_RETRY_LIMIT, rc = wl3501_get_mib_value(this, WL3501_MIB_ATTR_SHORT_RETRY_LIMIT,
&retry, sizeof(retry)); &retry, sizeof(retry));
if (rc) if (rc)
goto out; goto out;
wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN; wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_SHORT;
set_value: set_value:
wrqu->retry.value = retry; wrqu->retry.value = retry;
wrqu->retry.disabled = 0; wrqu->retry.disabled = 0;
......
...@@ -1218,7 +1218,7 @@ static int zd1201_set_essid(struct net_device *dev, ...@@ -1218,7 +1218,7 @@ static int zd1201_set_essid(struct net_device *dev,
return -EINVAL; return -EINVAL;
if (data->length < 1) if (data->length < 1)
data->length = 1; data->length = 1;
zd->essidlen = data->length-1; zd->essidlen = data->length;
memset(zd->essid, 0, IW_ESSID_MAX_SIZE+1); memset(zd->essid, 0, IW_ESSID_MAX_SIZE+1);
memcpy(zd->essid, essid, data->length); memcpy(zd->essid, essid, data->length);
return zd1201_join(zd, zd->essid, zd->essidlen); return zd1201_join(zd, zd->essid, zd->essidlen);
......
...@@ -249,7 +249,6 @@ int zd_ioread16(struct zd_chip *chip, zd_addr_t addr, u16 *value) ...@@ -249,7 +249,6 @@ int zd_ioread16(struct zd_chip *chip, zd_addr_t addr, u16 *value)
{ {
int r; int r;
ZD_ASSERT(!mutex_is_locked(&chip->mutex));
mutex_lock(&chip->mutex); mutex_lock(&chip->mutex);
r = zd_ioread16_locked(chip, value, addr); r = zd_ioread16_locked(chip, value, addr);
mutex_unlock(&chip->mutex); mutex_unlock(&chip->mutex);
...@@ -260,7 +259,6 @@ int zd_ioread32(struct zd_chip *chip, zd_addr_t addr, u32 *value) ...@@ -260,7 +259,6 @@ int zd_ioread32(struct zd_chip *chip, zd_addr_t addr, u32 *value)
{ {
int r; int r;
ZD_ASSERT(!mutex_is_locked(&chip->mutex));
mutex_lock(&chip->mutex); mutex_lock(&chip->mutex);
r = zd_ioread32_locked(chip, value, addr); r = zd_ioread32_locked(chip, value, addr);
mutex_unlock(&chip->mutex); mutex_unlock(&chip->mutex);
...@@ -271,7 +269,6 @@ int zd_iowrite16(struct zd_chip *chip, zd_addr_t addr, u16 value) ...@@ -271,7 +269,6 @@ int zd_iowrite16(struct zd_chip *chip, zd_addr_t addr, u16 value)
{ {
int r; int r;
ZD_ASSERT(!mutex_is_locked(&chip->mutex));
mutex_lock(&chip->mutex); mutex_lock(&chip->mutex);
r = zd_iowrite16_locked(chip, value, addr); r = zd_iowrite16_locked(chip, value, addr);
mutex_unlock(&chip->mutex); mutex_unlock(&chip->mutex);
...@@ -282,7 +279,6 @@ int zd_iowrite32(struct zd_chip *chip, zd_addr_t addr, u32 value) ...@@ -282,7 +279,6 @@ int zd_iowrite32(struct zd_chip *chip, zd_addr_t addr, u32 value)
{ {
int r; int r;
ZD_ASSERT(!mutex_is_locked(&chip->mutex));
mutex_lock(&chip->mutex); mutex_lock(&chip->mutex);
r = zd_iowrite32_locked(chip, value, addr); r = zd_iowrite32_locked(chip, value, addr);
mutex_unlock(&chip->mutex); mutex_unlock(&chip->mutex);
...@@ -294,7 +290,6 @@ int zd_ioread32v(struct zd_chip *chip, const zd_addr_t *addresses, ...@@ -294,7 +290,6 @@ int zd_ioread32v(struct zd_chip *chip, const zd_addr_t *addresses,
{ {
int r; int r;
ZD_ASSERT(!mutex_is_locked(&chip->mutex));
mutex_lock(&chip->mutex); mutex_lock(&chip->mutex);
r = zd_ioread32v_locked(chip, values, addresses, count); r = zd_ioread32v_locked(chip, values, addresses, count);
mutex_unlock(&chip->mutex); mutex_unlock(&chip->mutex);
...@@ -306,7 +301,6 @@ int zd_iowrite32a(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs, ...@@ -306,7 +301,6 @@ int zd_iowrite32a(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs,
{ {
int r; int r;
ZD_ASSERT(!mutex_is_locked(&chip->mutex));
mutex_lock(&chip->mutex); mutex_lock(&chip->mutex);
r = zd_iowrite32a_locked(chip, ioreqs, count); r = zd_iowrite32a_locked(chip, ioreqs, count);
mutex_unlock(&chip->mutex); mutex_unlock(&chip->mutex);
...@@ -331,13 +325,22 @@ static int read_pod(struct zd_chip *chip, u8 *rf_type) ...@@ -331,13 +325,22 @@ static int read_pod(struct zd_chip *chip, u8 *rf_type)
chip->patch_cr157 = (value >> 13) & 0x1; chip->patch_cr157 = (value >> 13) & 0x1;
chip->patch_6m_band_edge = (value >> 21) & 0x1; chip->patch_6m_band_edge = (value >> 21) & 0x1;
chip->new_phy_layout = (value >> 31) & 0x1; chip->new_phy_layout = (value >> 31) & 0x1;
chip->link_led = ((value >> 4) & 1) ? LED1 : LED2;
chip->supports_tx_led = 1;
if (value & (1 << 24)) { /* LED scenario */
if (value & (1 << 29))
chip->supports_tx_led = 0;
}
dev_dbg_f(zd_chip_dev(chip), dev_dbg_f(zd_chip_dev(chip),
"RF %s %#01x PA type %#01x patch CCK %d patch CR157 %d " "RF %s %#01x PA type %#01x patch CCK %d patch CR157 %d "
"patch 6M %d new PHY %d\n", "patch 6M %d new PHY %d link LED%d tx led %d\n",
zd_rf_name(*rf_type), *rf_type, zd_rf_name(*rf_type), *rf_type,
chip->pa_type, chip->patch_cck_gain, chip->pa_type, chip->patch_cck_gain,
chip->patch_cr157, chip->patch_6m_band_edge, chip->new_phy_layout); chip->patch_cr157, chip->patch_6m_band_edge,
chip->new_phy_layout,
chip->link_led == LED1 ? 1 : 2,
chip->supports_tx_led);
return 0; return 0;
error: error:
*rf_type = 0; *rf_type = 0;
...@@ -1181,7 +1184,7 @@ static int update_pwr_int(struct zd_chip *chip, u8 channel) ...@@ -1181,7 +1184,7 @@ static int update_pwr_int(struct zd_chip *chip, u8 channel)
u8 value = chip->pwr_int_values[channel - 1]; u8 value = chip->pwr_int_values[channel - 1];
dev_dbg_f(zd_chip_dev(chip), "channel %d pwr_int %#04x\n", dev_dbg_f(zd_chip_dev(chip), "channel %d pwr_int %#04x\n",
channel, value); channel, value);
return zd_iowrite32_locked(chip, value, CR31); return zd_iowrite16_locked(chip, value, CR31);
} }
static int update_pwr_cal(struct zd_chip *chip, u8 channel) static int update_pwr_cal(struct zd_chip *chip, u8 channel)
...@@ -1189,12 +1192,12 @@ static int update_pwr_cal(struct zd_chip *chip, u8 channel) ...@@ -1189,12 +1192,12 @@ static int update_pwr_cal(struct zd_chip *chip, u8 channel)
u8 value = chip->pwr_cal_values[channel-1]; u8 value = chip->pwr_cal_values[channel-1];
dev_dbg_f(zd_chip_dev(chip), "channel %d pwr_cal %#04x\n", dev_dbg_f(zd_chip_dev(chip), "channel %d pwr_cal %#04x\n",
channel, value); channel, value);
return zd_iowrite32_locked(chip, value, CR68); return zd_iowrite16_locked(chip, value, CR68);
} }
static int update_ofdm_cal(struct zd_chip *chip, u8 channel) static int update_ofdm_cal(struct zd_chip *chip, u8 channel)
{ {
struct zd_ioreq32 ioreqs[3]; struct zd_ioreq16 ioreqs[3];
ioreqs[0].addr = CR67; ioreqs[0].addr = CR67;
ioreqs[0].value = chip->ofdm_cal_values[OFDM_36M_INDEX][channel-1]; ioreqs[0].value = chip->ofdm_cal_values[OFDM_36M_INDEX][channel-1];
...@@ -1206,7 +1209,7 @@ static int update_ofdm_cal(struct zd_chip *chip, u8 channel) ...@@ -1206,7 +1209,7 @@ static int update_ofdm_cal(struct zd_chip *chip, u8 channel)
dev_dbg_f(zd_chip_dev(chip), dev_dbg_f(zd_chip_dev(chip),
"channel %d ofdm_cal 36M %#04x 48M %#04x 54M %#04x\n", "channel %d ofdm_cal 36M %#04x 48M %#04x 54M %#04x\n",
channel, ioreqs[0].value, ioreqs[1].value, ioreqs[2].value); channel, ioreqs[0].value, ioreqs[1].value, ioreqs[2].value);
return zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
} }
static int update_channel_integration_and_calibration(struct zd_chip *chip, static int update_channel_integration_and_calibration(struct zd_chip *chip,
...@@ -1218,7 +1221,7 @@ static int update_channel_integration_and_calibration(struct zd_chip *chip, ...@@ -1218,7 +1221,7 @@ static int update_channel_integration_and_calibration(struct zd_chip *chip,
if (r) if (r)
return r; return r;
if (chip->is_zd1211b) { if (chip->is_zd1211b) {
static const struct zd_ioreq32 ioreqs[] = { static const struct zd_ioreq16 ioreqs[] = {
{ CR69, 0x28 }, { CR69, 0x28 },
{}, {},
{ CR69, 0x2a }, { CR69, 0x2a },
...@@ -1230,7 +1233,7 @@ static int update_channel_integration_and_calibration(struct zd_chip *chip, ...@@ -1230,7 +1233,7 @@ static int update_channel_integration_and_calibration(struct zd_chip *chip,
r = update_pwr_cal(chip, channel); r = update_pwr_cal(chip, channel);
if (r) if (r)
return r; return r;
r = zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
if (r) if (r)
return r; return r;
} }
...@@ -1252,7 +1255,7 @@ static int patch_cck_gain(struct zd_chip *chip) ...@@ -1252,7 +1255,7 @@ static int patch_cck_gain(struct zd_chip *chip)
if (r) if (r)
return r; return r;
dev_dbg_f(zd_chip_dev(chip), "patching value %x\n", value & 0xff); dev_dbg_f(zd_chip_dev(chip), "patching value %x\n", value & 0xff);
return zd_iowrite32_locked(chip, value & 0xff, CR47); return zd_iowrite16_locked(chip, value & 0xff, CR47);
} }
int zd_chip_set_channel(struct zd_chip *chip, u8 channel) int zd_chip_set_channel(struct zd_chip *chip, u8 channel)
...@@ -1295,89 +1298,60 @@ u8 zd_chip_get_channel(struct zd_chip *chip) ...@@ -1295,89 +1298,60 @@ u8 zd_chip_get_channel(struct zd_chip *chip)
return channel; return channel;
} }
static u16 led_mask(int led) int zd_chip_control_leds(struct zd_chip *chip, enum led_status status)
{ {
switch (led) { static const zd_addr_t a[] = {
case 1: FW_LINK_STATUS,
return LED1; CR_LED,
case 2: };
return LED2;
default:
return 0;
}
}
static int read_led_reg(struct zd_chip *chip, u16 *status)
{
ZD_ASSERT(mutex_is_locked(&chip->mutex));
return zd_ioread16_locked(chip, status, CR_LED);
}
static int write_led_reg(struct zd_chip *chip, u16 status)
{
ZD_ASSERT(mutex_is_locked(&chip->mutex));
return zd_iowrite16_locked(chip, status, CR_LED);
}
int zd_chip_led_status(struct zd_chip *chip, int led, enum led_status status) int r;
{ u16 v[ARRAY_SIZE(a)];
int r, ret; struct zd_ioreq16 ioreqs[ARRAY_SIZE(a)] = {
u16 mask = led_mask(led); [0] = { FW_LINK_STATUS },
u16 reg; [1] = { CR_LED },
};
u16 other_led;
if (!mask)
return -EINVAL;
mutex_lock(&chip->mutex); mutex_lock(&chip->mutex);
r = read_led_reg(chip, &reg); r = zd_ioread16v_locked(chip, v, (const zd_addr_t *)a, ARRAY_SIZE(a));
if (r) if (r)
return r; goto out;
other_led = chip->link_led == LED1 ? LED2 : LED1;
switch (status) { switch (status) {
case LED_STATUS:
return (reg & mask) ? LED_ON : LED_OFF;
case LED_OFF: case LED_OFF:
reg &= ~mask; ioreqs[0].value = FW_LINK_OFF;
ret = LED_OFF; ioreqs[1].value = v[1] & ~(LED1|LED2);
break; break;
case LED_FLIP: case LED_SCANNING:
reg ^= mask; ioreqs[0].value = FW_LINK_OFF;
ret = (reg&mask) ? LED_ON : LED_OFF; ioreqs[1].value = v[1] & ~other_led;
if (get_seconds() % 3 == 0) {
ioreqs[1].value &= ~chip->link_led;
} else {
ioreqs[1].value |= chip->link_led;
}
break; break;
case LED_ON: case LED_ASSOCIATED:
reg |= mask; ioreqs[0].value = FW_LINK_TX;
ret = LED_ON; ioreqs[1].value = v[1] & ~other_led;
ioreqs[1].value |= chip->link_led;
break; break;
default: default:
return -EINVAL; r = -EINVAL;
}
r = write_led_reg(chip, reg);
if (r) {
ret = r;
goto out; goto out;
} }
out:
mutex_unlock(&chip->mutex);
return r;
}
int zd_chip_led_flip(struct zd_chip *chip, int led,
const unsigned int *phases_msecs, unsigned int count)
{
int i, r;
enum led_status status;
r = zd_chip_led_status(chip, led, LED_STATUS); if (v[0] != ioreqs[0].value || v[1] != ioreqs[1].value) {
if (r) r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
return r; if (r)
status = r;
for (i = 0; i < count; i++) {
r = zd_chip_led_status(chip, led, LED_FLIP);
if (r < 0)
goto out; goto out;
msleep(phases_msecs[i]);
} }
r = 0;
out: out:
zd_chip_led_status(chip, led, status); mutex_unlock(&chip->mutex);
return r; return r;
} }
...@@ -1679,4 +1653,3 @@ int zd_rfwritev_cr_locked(struct zd_chip *chip, ...@@ -1679,4 +1653,3 @@ int zd_rfwritev_cr_locked(struct zd_chip *chip,
return 0; return 0;
} }
...@@ -428,6 +428,7 @@ ...@@ -428,6 +428,7 @@
/* masks for controlling LEDs */ /* masks for controlling LEDs */
#define LED1 0x0100 #define LED1 0x0100
#define LED2 0x0200 #define LED2 0x0200
#define LED_SW 0x0400
/* Seems to indicate that the configuration is over. /* Seems to indicate that the configuration is over.
*/ */
...@@ -629,6 +630,10 @@ ...@@ -629,6 +630,10 @@
#define FW_SOFT_RESET FW_REG(4) #define FW_SOFT_RESET FW_REG(4)
#define FW_FLASH_CHK FW_REG(5) #define FW_FLASH_CHK FW_REG(5)
#define FW_LINK_OFF 0x0
#define FW_LINK_TX 0x1
/* 0x2 - link led on? */
enum { enum {
CR_BASE_OFFSET = 0x9000, CR_BASE_OFFSET = 0x9000,
FW_START_OFFSET = 0xee00, FW_START_OFFSET = 0xee00,
...@@ -663,8 +668,11 @@ struct zd_chip { ...@@ -663,8 +668,11 @@ struct zd_chip {
u8 pwr_int_values[E2P_CHANNEL_COUNT]; u8 pwr_int_values[E2P_CHANNEL_COUNT];
/* SetPointOFDM in the vendor driver */ /* SetPointOFDM in the vendor driver */
u8 ofdm_cal_values[3][E2P_CHANNEL_COUNT]; u8 ofdm_cal_values[3][E2P_CHANNEL_COUNT];
u8 pa_type:4, patch_cck_gain:1, patch_cr157:1, patch_6m_band_edge:1, u16 link_led;
new_phy_layout:1, is_zd1211b:1; unsigned int pa_type:4,
patch_cck_gain:1, patch_cr157:1, patch_6m_band_edge:1,
new_phy_layout:1,
is_zd1211b:1, supports_tx_led:1;
}; };
static inline struct zd_chip *zd_usb_to_chip(struct zd_usb *usb) static inline struct zd_chip *zd_usb_to_chip(struct zd_usb *usb)
...@@ -812,15 +820,12 @@ int zd_chip_lock_phy_regs(struct zd_chip *chip); ...@@ -812,15 +820,12 @@ int zd_chip_lock_phy_regs(struct zd_chip *chip);
int zd_chip_unlock_phy_regs(struct zd_chip *chip); int zd_chip_unlock_phy_regs(struct zd_chip *chip);
enum led_status { enum led_status {
LED_OFF = 0, LED_OFF = 0,
LED_ON = 1, LED_SCANNING = 1,
LED_FLIP = 2, LED_ASSOCIATED = 2,
LED_STATUS = 3,
}; };
int zd_chip_led_status(struct zd_chip *chip, int led, enum led_status status); int zd_chip_control_leds(struct zd_chip *chip, enum led_status status);
int zd_chip_led_flip(struct zd_chip *chip, int led,
const unsigned int *phases_msecs, unsigned int count);
int zd_set_beacon_interval(struct zd_chip *chip, u32 interval); int zd_set_beacon_interval(struct zd_chip *chip, u32 interval);
......
...@@ -33,6 +33,10 @@ ...@@ -33,6 +33,10 @@
static void ieee_init(struct ieee80211_device *ieee); static void ieee_init(struct ieee80211_device *ieee);
static void softmac_init(struct ieee80211softmac_device *sm); static void softmac_init(struct ieee80211softmac_device *sm);
static void housekeeping_init(struct zd_mac *mac);
static void housekeeping_enable(struct zd_mac *mac);
static void housekeeping_disable(struct zd_mac *mac);
int zd_mac_init(struct zd_mac *mac, int zd_mac_init(struct zd_mac *mac,
struct net_device *netdev, struct net_device *netdev,
struct usb_interface *intf) struct usb_interface *intf)
...@@ -46,6 +50,7 @@ int zd_mac_init(struct zd_mac *mac, ...@@ -46,6 +50,7 @@ int zd_mac_init(struct zd_mac *mac,
ieee_init(ieee); ieee_init(ieee);
softmac_init(ieee80211_priv(netdev)); softmac_init(ieee80211_priv(netdev));
zd_chip_init(&mac->chip, netdev, intf); zd_chip_init(&mac->chip, netdev, intf);
housekeeping_init(mac);
return 0; return 0;
} }
...@@ -178,6 +183,7 @@ int zd_mac_open(struct net_device *netdev) ...@@ -178,6 +183,7 @@ int zd_mac_open(struct net_device *netdev)
if (r < 0) if (r < 0)
goto disable_rx; goto disable_rx;
housekeeping_enable(mac);
ieee80211softmac_start(netdev); ieee80211softmac_start(netdev);
return 0; return 0;
disable_rx: disable_rx:
...@@ -204,6 +210,7 @@ int zd_mac_stop(struct net_device *netdev) ...@@ -204,6 +210,7 @@ int zd_mac_stop(struct net_device *netdev)
*/ */
zd_chip_disable_rx(chip); zd_chip_disable_rx(chip);
housekeeping_disable(mac);
ieee80211softmac_stop(netdev); ieee80211softmac_stop(netdev);
zd_chip_disable_hwint(chip); zd_chip_disable_hwint(chip);
...@@ -1080,3 +1087,46 @@ void zd_dump_rx_status(const struct rx_status *status) ...@@ -1080,3 +1087,46 @@ void zd_dump_rx_status(const struct rx_status *status)
} }
} }
#endif /* DEBUG */ #endif /* DEBUG */
#define LINK_LED_WORK_DELAY HZ
static void link_led_handler(void *p)
{
struct zd_mac *mac = p;
struct zd_chip *chip = &mac->chip;
struct ieee80211softmac_device *sm = ieee80211_priv(mac->netdev);
int is_associated;
int r;
spin_lock_irq(&mac->lock);
is_associated = sm->associated != 0;
spin_unlock_irq(&mac->lock);
r = zd_chip_control_leds(chip,
is_associated ? LED_ASSOCIATED : LED_SCANNING);
if (r)
dev_err(zd_mac_dev(mac), "zd_chip_control_leds error %d\n", r);
queue_delayed_work(zd_workqueue, &mac->housekeeping.link_led_work,
LINK_LED_WORK_DELAY);
}
static void housekeeping_init(struct zd_mac *mac)
{
INIT_WORK(&mac->housekeeping.link_led_work, link_led_handler, mac);
}
static void housekeeping_enable(struct zd_mac *mac)
{
dev_dbg_f(zd_mac_dev(mac), "\n");
queue_delayed_work(zd_workqueue, &mac->housekeeping.link_led_work,
0);
}
static void housekeeping_disable(struct zd_mac *mac)
{
dev_dbg_f(zd_mac_dev(mac), "\n");
cancel_rearming_delayed_workqueue(zd_workqueue,
&mac->housekeeping.link_led_work);
zd_chip_control_leds(&mac->chip, LED_OFF);
}
...@@ -120,6 +120,10 @@ enum mac_flags { ...@@ -120,6 +120,10 @@ enum mac_flags {
MAC_FIXED_CHANNEL = 0x01, MAC_FIXED_CHANNEL = 0x01,
}; };
struct housekeeping {
struct work_struct link_led_work;
};
#define ZD_MAC_STATS_BUFFER_SIZE 16 #define ZD_MAC_STATS_BUFFER_SIZE 16
struct zd_mac { struct zd_mac {
...@@ -128,6 +132,7 @@ struct zd_mac { ...@@ -128,6 +132,7 @@ struct zd_mac {
struct net_device *netdev; struct net_device *netdev;
/* Unlocked reading possible */ /* Unlocked reading possible */
struct iw_statistics iw_stats; struct iw_statistics iw_stats;
struct housekeeping housekeeping;
unsigned int stats_count; unsigned int stats_count;
u8 qual_buffer[ZD_MAC_STATS_BUFFER_SIZE]; u8 qual_buffer[ZD_MAC_STATS_BUFFER_SIZE];
u8 rssi_buffer[ZD_MAC_STATS_BUFFER_SIZE]; u8 rssi_buffer[ZD_MAC_STATS_BUFFER_SIZE];
......
...@@ -82,7 +82,7 @@ static int iw_get_nick(struct net_device *netdev, ...@@ -82,7 +82,7 @@ static int iw_get_nick(struct net_device *netdev,
union iwreq_data *req, char *extra) union iwreq_data *req, char *extra)
{ {
strcpy(extra, "zd1211"); strcpy(extra, "zd1211");
req->data.length = strlen(extra) + 1; req->data.length = strlen(extra);
req->data.flags = 1; req->data.flags = 1;
return 0; return 0;
} }
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/workqueue.h>
#include <net/ieee80211.h> #include <net/ieee80211.h>
#include "zd_def.h" #include "zd_def.h"
...@@ -1112,12 +1113,20 @@ static struct usb_driver driver = { ...@@ -1112,12 +1113,20 @@ static struct usb_driver driver = {
.disconnect = disconnect, .disconnect = disconnect,
}; };
struct workqueue_struct *zd_workqueue;
static int __init usb_init(void) static int __init usb_init(void)
{ {
int r; int r;
pr_debug("usb_init()\n"); pr_debug("usb_init()\n");
zd_workqueue = create_singlethread_workqueue(driver.name);
if (zd_workqueue == NULL) {
printk(KERN_ERR "%s: couldn't create workqueue\n", driver.name);
return -ENOMEM;
}
r = usb_register(&driver); r = usb_register(&driver);
if (r) { if (r) {
printk(KERN_ERR "usb_register() failed. Error number %d\n", r); printk(KERN_ERR "usb_register() failed. Error number %d\n", r);
...@@ -1132,6 +1141,7 @@ static void __exit usb_exit(void) ...@@ -1132,6 +1141,7 @@ static void __exit usb_exit(void)
{ {
pr_debug("usb_exit()\n"); pr_debug("usb_exit()\n");
usb_deregister(&driver); usb_deregister(&driver);
destroy_workqueue(zd_workqueue);
} }
module_init(usb_init); module_init(usb_init);
......
...@@ -238,4 +238,6 @@ int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, ...@@ -238,4 +238,6 @@ int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs,
int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits); int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits);
extern struct workqueue_struct *zd_workqueue;
#endif /* _ZD_USB_H */ #endif /* _ZD_USB_H */
...@@ -334,7 +334,6 @@ struct net_device ...@@ -334,7 +334,6 @@ struct net_device
struct net_device_stats* (*get_stats)(struct net_device *dev); struct net_device_stats* (*get_stats)(struct net_device *dev);
struct iw_statistics* (*get_wireless_stats)(struct net_device *dev);
/* List of functions to handle Wireless Extensions (instead of ioctl). /* List of functions to handle Wireless Extensions (instead of ioctl).
* See <net/iw_handler.h> for details. Jean II */ * See <net/iw_handler.h> for details. Jean II */
......
/* /*
* This file define a set of standard wireless extensions * This file define a set of standard wireless extensions
* *
* Version : 20 17.2.06 * Version : 21 14.3.06
* *
* Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com> * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
* Copyright (c) 1997-2006 Jean Tourrilhes, All Rights Reserved. * Copyright (c) 1997-2006 Jean Tourrilhes, All Rights Reserved.
...@@ -69,9 +69,14 @@ ...@@ -69,9 +69,14 @@
/***************************** INCLUDES *****************************/ /***************************** INCLUDES *****************************/
/* This header is used in user-space, therefore need to be sanitised
* for that purpose. Those includes are usually not compatible with glibc.
* To know which includes to use in user-space, check iwlib.h. */
#ifdef __KERNEL__
#include <linux/types.h> /* for "caddr_t" et al */ #include <linux/types.h> /* for "caddr_t" et al */
#include <linux/socket.h> /* for "struct sockaddr" et al */ #include <linux/socket.h> /* for "struct sockaddr" et al */
#include <linux/if.h> /* for IFNAMSIZ and co... */ #include <linux/if.h> /* for IFNAMSIZ and co... */
#endif /* __KERNEL__ */
/***************************** VERSION *****************************/ /***************************** VERSION *****************************/
/* /*
...@@ -80,7 +85,7 @@ ...@@ -80,7 +85,7 @@
* (there is some stuff that will be added in the future...) * (there is some stuff that will be added in the future...)
* I just plan to increment with each new version. * I just plan to increment with each new version.
*/ */
#define WIRELESS_EXT 20 #define WIRELESS_EXT 21
/* /*
* Changes : * Changes :
...@@ -208,6 +213,14 @@ ...@@ -208,6 +213,14 @@
* V19 to V20 * V19 to V20
* ---------- * ----------
* - RtNetlink requests support (SET/GET) * - RtNetlink requests support (SET/GET)
*
* V20 to V21
* ----------
* - Remove (struct net_device *)->get_wireless_stats()
* - Change length in ESSID and NICK to strlen() instead of strlen()+1
* - Add IW_RETRY_SHORT/IW_RETRY_LONG retry modifiers
* - Power/Retry relative values no longer * 100000
* - Add explicit flag to tell stats are in 802.11k RCPI : IW_QUAL_RCPI
*/ */
/**************************** CONSTANTS ****************************/ /**************************** CONSTANTS ****************************/
...@@ -448,6 +461,7 @@ ...@@ -448,6 +461,7 @@
#define IW_QUAL_QUAL_INVALID 0x10 /* Driver doesn't provide value */ #define IW_QUAL_QUAL_INVALID 0x10 /* Driver doesn't provide value */
#define IW_QUAL_LEVEL_INVALID 0x20 #define IW_QUAL_LEVEL_INVALID 0x20
#define IW_QUAL_NOISE_INVALID 0x40 #define IW_QUAL_NOISE_INVALID 0x40
#define IW_QUAL_RCPI 0x80 /* Level + Noise are 802.11k RCPI */
#define IW_QUAL_ALL_INVALID 0x70 #define IW_QUAL_ALL_INVALID 0x70
/* Frequency flags */ /* Frequency flags */
...@@ -500,10 +514,12 @@ ...@@ -500,10 +514,12 @@
#define IW_RETRY_TYPE 0xF000 /* Type of parameter */ #define IW_RETRY_TYPE 0xF000 /* Type of parameter */
#define IW_RETRY_LIMIT 0x1000 /* Maximum number of retries*/ #define IW_RETRY_LIMIT 0x1000 /* Maximum number of retries*/
#define IW_RETRY_LIFETIME 0x2000 /* Maximum duration of retries in us */ #define IW_RETRY_LIFETIME 0x2000 /* Maximum duration of retries in us */
#define IW_RETRY_MODIFIER 0x000F /* Modify a parameter */ #define IW_RETRY_MODIFIER 0x00FF /* Modify a parameter */
#define IW_RETRY_MIN 0x0001 /* Value is a minimum */ #define IW_RETRY_MIN 0x0001 /* Value is a minimum */
#define IW_RETRY_MAX 0x0002 /* Value is a maximum */ #define IW_RETRY_MAX 0x0002 /* Value is a maximum */
#define IW_RETRY_RELATIVE 0x0004 /* Value is not in seconds/ms/us */ #define IW_RETRY_RELATIVE 0x0004 /* Value is not in seconds/ms/us */
#define IW_RETRY_SHORT 0x0010 /* Value is for short packets */
#define IW_RETRY_LONG 0x0020 /* Value is for long packets */
/* Scanning request flags */ /* Scanning request flags */
#define IW_SCAN_DEFAULT 0x0000 /* Default scan of the driver */ #define IW_SCAN_DEFAULT 0x0000 /* Default scan of the driver */
...@@ -1017,7 +1033,7 @@ struct iw_range ...@@ -1017,7 +1033,7 @@ struct iw_range
/* Note : this frequency list doesn't need to fit channel numbers, /* Note : this frequency list doesn't need to fit channel numbers,
* because each entry contain its channel index */ * because each entry contain its channel index */
__u32 enc_capa; /* IW_ENC_CAPA_* bit field */ __u32 enc_capa; /* IW_ENC_CAPA_* bit field */
}; };
/* /*
......
...@@ -344,8 +344,6 @@ static ssize_t wireless_show(struct class_device *cd, char *buf, ...@@ -344,8 +344,6 @@ static ssize_t wireless_show(struct class_device *cd, char *buf,
if(dev->wireless_handlers && if(dev->wireless_handlers &&
dev->wireless_handlers->get_wireless_stats) dev->wireless_handlers->get_wireless_stats)
iw = dev->wireless_handlers->get_wireless_stats(dev); iw = dev->wireless_handlers->get_wireless_stats(dev);
else if (dev->get_wireless_stats)
iw = dev->get_wireless_stats(dev);
if (iw != NULL) if (iw != NULL)
ret = (*format)(iw, buf); ret = (*format)(iw, buf);
} }
...@@ -465,8 +463,7 @@ int netdev_register_sysfs(struct net_device *net) ...@@ -465,8 +463,7 @@ int netdev_register_sysfs(struct net_device *net)
*groups++ = &netstat_group; *groups++ = &netstat_group;
#ifdef WIRELESS_EXT #ifdef WIRELESS_EXT
if (net->get_wireless_stats if (net->wireless_handlers && net->wireless_handlers->get_wireless_stats)
|| (net->wireless_handlers && net->wireless_handlers->get_wireless_stats))
*groups++ = &wireless_group; *groups++ = &wireless_group;
#endif #endif
......
...@@ -68,6 +68,14 @@ ...@@ -68,6 +68,14 @@
* *
* v8 - 17.02.06 - Jean II * v8 - 17.02.06 - Jean II
* o RtNetlink requests support (SET/GET) * o RtNetlink requests support (SET/GET)
*
* v8b - 03.08.06 - Herbert Xu
* o Fix Wireless Event locking issues.
*
* v9 - 14.3.06 - Jean II
* o Change length in ESSID and NICK to strlen() instead of strlen()+1
* o Make standard_ioctl_num and standard_event_num unsigned
* o Remove (struct net_device *)->get_wireless_stats()
*/ */
/***************************** INCLUDES *****************************/ /***************************** INCLUDES *****************************/
...@@ -234,24 +242,24 @@ static const struct iw_ioctl_description standard_ioctl[] = { ...@@ -234,24 +242,24 @@ static const struct iw_ioctl_description standard_ioctl[] = {
[SIOCSIWESSID - SIOCIWFIRST] = { [SIOCSIWESSID - SIOCIWFIRST] = {
.header_type = IW_HEADER_TYPE_POINT, .header_type = IW_HEADER_TYPE_POINT,
.token_size = 1, .token_size = 1,
.max_tokens = IW_ESSID_MAX_SIZE + 1, .max_tokens = IW_ESSID_MAX_SIZE,
.flags = IW_DESCR_FLAG_EVENT, .flags = IW_DESCR_FLAG_EVENT,
}, },
[SIOCGIWESSID - SIOCIWFIRST] = { [SIOCGIWESSID - SIOCIWFIRST] = {
.header_type = IW_HEADER_TYPE_POINT, .header_type = IW_HEADER_TYPE_POINT,
.token_size = 1, .token_size = 1,
.max_tokens = IW_ESSID_MAX_SIZE + 1, .max_tokens = IW_ESSID_MAX_SIZE,
.flags = IW_DESCR_FLAG_DUMP, .flags = IW_DESCR_FLAG_DUMP,
}, },
[SIOCSIWNICKN - SIOCIWFIRST] = { [SIOCSIWNICKN - SIOCIWFIRST] = {
.header_type = IW_HEADER_TYPE_POINT, .header_type = IW_HEADER_TYPE_POINT,
.token_size = 1, .token_size = 1,
.max_tokens = IW_ESSID_MAX_SIZE + 1, .max_tokens = IW_ESSID_MAX_SIZE,
}, },
[SIOCGIWNICKN - SIOCIWFIRST] = { [SIOCGIWNICKN - SIOCIWFIRST] = {
.header_type = IW_HEADER_TYPE_POINT, .header_type = IW_HEADER_TYPE_POINT,
.token_size = 1, .token_size = 1,
.max_tokens = IW_ESSID_MAX_SIZE + 1, .max_tokens = IW_ESSID_MAX_SIZE,
}, },
[SIOCSIWRATE - SIOCIWFIRST] = { [SIOCSIWRATE - SIOCIWFIRST] = {
.header_type = IW_HEADER_TYPE_PARAM, .header_type = IW_HEADER_TYPE_PARAM,
...@@ -338,8 +346,8 @@ static const struct iw_ioctl_description standard_ioctl[] = { ...@@ -338,8 +346,8 @@ static const struct iw_ioctl_description standard_ioctl[] = {
.max_tokens = sizeof(struct iw_pmksa), .max_tokens = sizeof(struct iw_pmksa),
}, },
}; };
static const int standard_ioctl_num = (sizeof(standard_ioctl) / static const unsigned standard_ioctl_num = (sizeof(standard_ioctl) /
sizeof(struct iw_ioctl_description)); sizeof(struct iw_ioctl_description));
/* /*
* Meta-data about all the additional standard Wireless Extension events * Meta-data about all the additional standard Wireless Extension events
...@@ -389,8 +397,8 @@ static const struct iw_ioctl_description standard_event[] = { ...@@ -389,8 +397,8 @@ static const struct iw_ioctl_description standard_event[] = {
.max_tokens = sizeof(struct iw_pmkid_cand), .max_tokens = sizeof(struct iw_pmkid_cand),
}, },
}; };
static const int standard_event_num = (sizeof(standard_event) / static const unsigned standard_event_num = (sizeof(standard_event) /
sizeof(struct iw_ioctl_description)); sizeof(struct iw_ioctl_description));
/* Size (in bytes) of the various private data types */ /* Size (in bytes) of the various private data types */
static const char iw_priv_type_size[] = { static const char iw_priv_type_size[] = {
...@@ -465,17 +473,6 @@ static inline struct iw_statistics *get_wireless_stats(struct net_device *dev) ...@@ -465,17 +473,6 @@ static inline struct iw_statistics *get_wireless_stats(struct net_device *dev)
(dev->wireless_handlers->get_wireless_stats != NULL)) (dev->wireless_handlers->get_wireless_stats != NULL))
return dev->wireless_handlers->get_wireless_stats(dev); return dev->wireless_handlers->get_wireless_stats(dev);
/* Old location, field to be removed in next WE */
if(dev->get_wireless_stats) {
static int printed_message;
if (!printed_message++)
printk(KERN_DEBUG "%s (WE) : Driver using old /proc/net/wireless support, please fix driver !\n",
dev->name);
return dev->get_wireless_stats(dev);
}
/* Not found */ /* Not found */
return (struct iw_statistics *) NULL; return (struct iw_statistics *) NULL;
} }
...@@ -1843,8 +1840,33 @@ int wireless_rtnetlink_set(struct net_device * dev, ...@@ -1843,8 +1840,33 @@ int wireless_rtnetlink_set(struct net_device * dev,
*/ */
#ifdef WE_EVENT_RTNETLINK #ifdef WE_EVENT_RTNETLINK
/* ---------------------------------------------------------------- */
/*
* Locking...
* ----------
*
* Thanks to Herbert Xu <herbert@gondor.apana.org.au> for fixing
* the locking issue in here and implementing this code !
*
* The issue : wireless_send_event() is often called in interrupt context,
* while the Netlink layer can never be called in interrupt context.
* The fully formed RtNetlink events are queued, and then a tasklet is run
* to feed those to Netlink.
* The skb_queue is interrupt safe, and its lock is not held while calling
* Netlink, so there is no possibility of dealock.
* Jean II
*/
static struct sk_buff_head wireless_nlevent_queue; static struct sk_buff_head wireless_nlevent_queue;
static int __init wireless_nlevent_init(void)
{
skb_queue_head_init(&wireless_nlevent_queue);
return 0;
}
subsys_initcall(wireless_nlevent_init);
static void wireless_nlevent_process(unsigned long data) static void wireless_nlevent_process(unsigned long data)
{ {
struct sk_buff *skb; struct sk_buff *skb;
...@@ -1921,13 +1943,6 @@ static inline void rtmsg_iwinfo(struct net_device * dev, ...@@ -1921,13 +1943,6 @@ static inline void rtmsg_iwinfo(struct net_device * dev,
tasklet_schedule(&wireless_nlevent_tasklet); tasklet_schedule(&wireless_nlevent_tasklet);
} }
static int __init wireless_nlevent_init(void)
{
skb_queue_head_init(&wireless_nlevent_queue);
return 0;
}
subsys_initcall(wireless_nlevent_init);
#endif /* WE_EVENT_RTNETLINK */ #endif /* WE_EVENT_RTNETLINK */
/* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */
......
...@@ -80,10 +80,10 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev, ...@@ -80,10 +80,10 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev,
* If it's our network, ignore the change, we're already doing it! * If it's our network, ignore the change, we're already doing it!
*/ */
if((sm->associnfo.associating || sm->associated) && if((sm->associnfo.associating || sm->associated) &&
(data->essid.flags && data->essid.length && extra)) { (data->essid.flags && data->essid.length)) {
/* Get the associating network */ /* Get the associating network */
n = ieee80211softmac_get_network_by_bssid(sm, sm->associnfo.bssid); n = ieee80211softmac_get_network_by_bssid(sm, sm->associnfo.bssid);
if(n && n->essid.len == (data->essid.length - 1) && if(n && n->essid.len == data->essid.length &&
!memcmp(n->essid.data, extra, n->essid.len)) { !memcmp(n->essid.data, extra, n->essid.len)) {
dprintk(KERN_INFO PFX "Already associating or associated to "MAC_FMT"\n", dprintk(KERN_INFO PFX "Already associating or associated to "MAC_FMT"\n",
MAC_ARG(sm->associnfo.bssid)); MAC_ARG(sm->associnfo.bssid));
...@@ -109,8 +109,8 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev, ...@@ -109,8 +109,8 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev,
sm->associnfo.static_essid = 0; sm->associnfo.static_essid = 0;
sm->associnfo.assoc_wait = 0; sm->associnfo.assoc_wait = 0;
if (data->essid.flags && data->essid.length && extra /*required?*/) { if (data->essid.flags && data->essid.length) {
length = min(data->essid.length - 1, IW_ESSID_MAX_SIZE); length = min((int)data->essid.length, IW_ESSID_MAX_SIZE);
if (length) { if (length) {
memcpy(sm->associnfo.req_essid.data, extra, length); memcpy(sm->associnfo.req_essid.data, extra, length);
sm->associnfo.static_essid = 1; sm->associnfo.static_essid = 1;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册