Commit 54dceb00 authored by David S. Miller's avatar David S. Miller

Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/linville/wireless-next-2.6

parents 11a100f8 b4637271
......@@ -611,14 +611,20 @@ config RTL8180
Thanks to Realtek for their support!
config RTL8187
tristate "Realtek 8187 USB support"
tristate "Realtek 8187 and 8187B USB support"
depends on MAC80211 && USB && WLAN_80211 && EXPERIMENTAL
select EEPROM_93CX6
---help---
This is a driver for RTL8187 based cards.
These are USB based chips found in cards such as:
This is a driver for RTL8187 and RTL8187B based cards.
These are USB based chips found in devices such as:
Netgear WG111v2
Level 1 WNC-0301USB
Micronet SP907GK V5
Encore ENUWI-G2
Trendnet TEW-424UB
ASUS P5B Deluxe
Toshiba Satellite Pro series of laptops
Thanks to Realtek for their support!
......
......@@ -859,6 +859,18 @@ static u64 supported_dma_mask(struct b43legacy_wldev *dev)
return DMA_30BIT_MASK;
}
static enum b43legacy_dmatype dma_mask_to_engine_type(u64 dmamask)
{
if (dmamask == DMA_30BIT_MASK)
return B43legacy_DMA_30BIT;
if (dmamask == DMA_32BIT_MASK)
return B43legacy_DMA_32BIT;
if (dmamask == DMA_64BIT_MASK)
return B43legacy_DMA_64BIT;
B43legacy_WARN_ON(1);
return B43legacy_DMA_30BIT;
}
/* Main initialization function. */
static
struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev,
......@@ -1018,6 +1030,43 @@ void b43legacy_dma_free(struct b43legacy_wldev *dev)
dma->tx_ring0 = NULL;
}
static int b43legacy_dma_set_mask(struct b43legacy_wldev *dev, u64 mask)
{
u64 orig_mask = mask;
bool fallback = 0;
int err;
/* Try to set the DMA mask. If it fails, try falling back to a
* lower mask, as we can always also support a lower one. */
while (1) {
err = ssb_dma_set_mask(dev->dev, mask);
if (!err)
break;
if (mask == DMA_64BIT_MASK) {
mask = DMA_32BIT_MASK;
fallback = 1;
continue;
}
if (mask == DMA_32BIT_MASK) {
mask = DMA_30BIT_MASK;
fallback = 1;
continue;
}
b43legacyerr(dev->wl, "The machine/kernel does not support "
"the required %u-bit DMA mask\n",
(unsigned int)dma_mask_to_engine_type(orig_mask));
return -EOPNOTSUPP;
}
if (fallback) {
b43legacyinfo(dev->wl, "DMA mask fallback from %u-bit to %u-"
"bit\n",
(unsigned int)dma_mask_to_engine_type(orig_mask),
(unsigned int)dma_mask_to_engine_type(mask));
}
return 0;
}
int b43legacy_dma_init(struct b43legacy_wldev *dev)
{
struct b43legacy_dma *dma = &dev->dma;
......@@ -1027,21 +1076,8 @@ int b43legacy_dma_init(struct b43legacy_wldev *dev)
enum b43legacy_dmatype type;
dmamask = supported_dma_mask(dev);
switch (dmamask) {
default:
B43legacy_WARN_ON(1);
case DMA_30BIT_MASK:
type = B43legacy_DMA_30BIT;
break;
case DMA_32BIT_MASK:
type = B43legacy_DMA_32BIT;
break;
case DMA_64BIT_MASK:
type = B43legacy_DMA_64BIT;
break;
}
err = ssb_dma_set_mask(dev->dev, dmamask);
type = dma_mask_to_engine_type(dmamask);
err = b43legacy_dma_set_mask(dev, dmamask);
if (err) {
#ifdef CONFIG_B43LEGACY_PIO
b43legacywarn(dev->wl, "DMA for this device not supported. "
......
......@@ -3417,7 +3417,7 @@ static void prism2_free_local_data(struct net_device *dev)
}
#ifndef PRISM2_PLX
#if (defined(PRISM2_PCI) && defined(CONFIG_PM)) || defined(PRISM2_PCCARD)
static void prism2_suspend(struct net_device *dev)
{
struct hostap_interface *iface;
......@@ -3436,7 +3436,7 @@ static void prism2_suspend(struct net_device *dev)
/* Disable hardware and firmware */
prism2_hw_shutdown(dev, 0);
}
#endif /* PRISM2_PLX */
#endif /* (PRISM2_PCI && CONFIG_PM) || PRISM2_PCCARD */
/* These might at some point be compiled separately and used as separate
......
......@@ -104,6 +104,7 @@ config IWL3945
select IWLWIFI
select MAC80211_LEDS if IWL3945_LEDS
select LEDS_CLASS if IWL3945_LEDS
select RFKILL if IWL3945_RFKILL
---help---
Select to build the driver supporting the:
......@@ -126,6 +127,10 @@ config IWL3945
say M here and read <file:Documentation/kbuild/modules.txt>. The
module will be called iwl3945.ko.
config IWL3945_RFKILL
bool "Enable RF kill support in iwl3945 drivers"
depends on IWL3945
config IWL3945_SPECTRUM_MEASUREMENT
bool "Enable Spectrum Measurement in iwl3945 drivers"
depends on IWL3945
......
......@@ -690,14 +690,9 @@ enum {
#endif
#ifdef CONFIG_IWLWIFI_RFKILL
#ifdef CONFIG_IWL3945_RFKILL
struct iwl3945_priv;
struct iwl3945_rfkill_mngr {
struct rfkill *rfkill;
struct input_dev *input_dev;
};
void iwl3945_rfkill_set_hw_state(struct iwl3945_priv *priv);
void iwl3945_rfkill_unregister(struct iwl3945_priv *priv);
int iwl3945_rfkill_init(struct iwl3945_priv *priv);
......@@ -800,8 +795,8 @@ struct iwl3945_priv {
struct iwl3945_init_alive_resp card_alive_init;
struct iwl3945_alive_resp card_alive;
#ifdef CONFIG_IWLWIFI_RFKILL
struct iwl3945_rfkill_mngr rfkill_mngr;
#ifdef CONFIG_IWL3945_RFKILL
struct rfkill *rfkill;
#endif
#ifdef CONFIG_IWL3945_LEDS
......
......@@ -2285,9 +2285,9 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
iwl4965_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index);
if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status)) {
/* TODO: send BAR */
}
/* check if BAR is needed */
if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status))
info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
if (txq->q.read_ptr != (scd_ssn & 0xff)) {
int freed, ampdu_q;
......
......@@ -1278,9 +1278,9 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
iwl5000_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index);
if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status)) {
/* TODO: send BAR */
}
/* check if BAR is needed */
if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status))
info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
if (txq->q.read_ptr != (scd_ssn & 0xff)) {
int freed, ampdu_q;
......
......@@ -356,10 +356,19 @@ static inline int iwl_is_init(struct iwl_priv *priv)
return test_bit(STATUS_INIT, &priv->status);
}
static inline int iwl_is_rfkill_sw(struct iwl_priv *priv)
{
return test_bit(STATUS_RF_KILL_SW, &priv->status);
}
static inline int iwl_is_rfkill_hw(struct iwl_priv *priv)
{
return test_bit(STATUS_RF_KILL_HW, &priv->status);
}
static inline int iwl_is_rfkill(struct iwl_priv *priv)
{
return test_bit(STATUS_RF_KILL_HW, &priv->status) ||
test_bit(STATUS_RF_KILL_SW, &priv->status);
return iwl_is_rfkill_hw(priv) || iwl_is_rfkill_sw(priv);
}
static inline int iwl_is_ready_rf(struct iwl_priv *priv)
......
......@@ -929,7 +929,7 @@ struct iwl_priv {
struct iwl_init_alive_resp card_alive_init;
struct iwl_alive_resp card_alive;
#ifdef CONFIG_IWLWIFI_RFKILL
struct iwl_rfkill_mngr rfkill_mngr;
struct rfkill *rfkill;
#endif
#ifdef CONFIG_IWLWIFI_LEDS
......@@ -1103,7 +1103,7 @@ static inline void iwl_txq_ctx_deactivate(struct iwl_priv *priv, int txq_id)
clear_bit(txq_id, &priv->txq_ctx_active_msk);
}
#ifdef CONFIG_IWLWIF_DEBUG
#ifdef CONFIG_IWLWIFI_DEBUG
const char *iwl_get_tx_fail_reason(u32 status);
#else
static inline const char *iwl_get_tx_fail_reason(u32 status) { return ""; }
......
......@@ -44,7 +44,7 @@ static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
struct iwl_priv *priv = data;
int err = 0;
if (!priv->rfkill_mngr.rfkill)
if (!priv->rfkill)
return 0;
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
......@@ -55,20 +55,20 @@ static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
switch (state) {
case RFKILL_STATE_UNBLOCKED:
iwl_radio_kill_sw_enable_radio(priv);
/* if HW rf-kill is set dont allow ON state */
if (iwl_is_rfkill(priv))
if (iwl_is_rfkill_hw(priv)) {
err = -EBUSY;
goto out_unlock;
}
iwl_radio_kill_sw_enable_radio(priv);
break;
case RFKILL_STATE_SOFT_BLOCKED:
iwl_radio_kill_sw_disable_radio(priv);
if (!iwl_is_rfkill(priv))
err = -EBUSY;
break;
default:
IWL_WARNING("we recieved unexpected RFKILL state %d\n", state);
break;
}
out_unlock:
mutex_unlock(&priv->mutex);
return err;
......@@ -82,39 +82,35 @@ int iwl_rfkill_init(struct iwl_priv *priv)
BUG_ON(device == NULL);
IWL_DEBUG_RF_KILL("Initializing RFKILL.\n");
priv->rfkill_mngr.rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN);
if (!priv->rfkill_mngr.rfkill) {
priv->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN);
if (!priv->rfkill) {
IWL_ERROR("Unable to allocate rfkill device.\n");
ret = -ENOMEM;
goto error;
}
priv->rfkill_mngr.rfkill->name = priv->cfg->name;
priv->rfkill_mngr.rfkill->data = priv;
priv->rfkill_mngr.rfkill->state = RFKILL_STATE_ON;
priv->rfkill_mngr.rfkill->toggle_radio = iwl_rfkill_soft_rf_kill;
priv->rfkill_mngr.rfkill->user_claim_unsupported = 1;
priv->rfkill->name = priv->cfg->name;
priv->rfkill->data = priv;
priv->rfkill->state = RFKILL_STATE_UNBLOCKED;
priv->rfkill->toggle_radio = iwl_rfkill_soft_rf_kill;
priv->rfkill->user_claim_unsupported = 1;
priv->rfkill_mngr.rfkill->dev.class->suspend = NULL;
priv->rfkill_mngr.rfkill->dev.class->resume = NULL;
priv->rfkill->dev.class->suspend = NULL;
priv->rfkill->dev.class->resume = NULL;
ret = rfkill_register(priv->rfkill_mngr.rfkill);
ret = rfkill_register(priv->rfkill);
if (ret) {
IWL_ERROR("Unable to register rfkill: %d\n", ret);
goto unregister_rfkill;
goto free_rfkill;
}
IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
return ret;
unregister_rfkill:
rfkill_unregister(priv->rfkill_mngr.rfkill);
priv->rfkill_mngr.rfkill = NULL;
freed_rfkill:
if (priv->rfkill_mngr.rfkill != NULL)
rfkill_free(priv->rfkill_mngr.rfkill);
priv->rfkill_mngr.rfkill = NULL;
free_rfkill:
if (priv->rfkill != NULL)
rfkill_free(priv->rfkill);
priv->rfkill = NULL;
error:
IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
......@@ -125,22 +121,27 @@ EXPORT_SYMBOL(iwl_rfkill_init);
void iwl_rfkill_unregister(struct iwl_priv *priv)
{
if (priv->rfkill_mngr.rfkill)
rfkill_unregister(priv->rfkill_mngr.rfkill);
if (priv->rfkill)
rfkill_unregister(priv->rfkill);
priv->rfkill_mngr.rfkill = NULL;
priv->rfkill = NULL;
}
EXPORT_SYMBOL(iwl_rfkill_unregister);
/* set rf-kill to the right state. */
void iwl_rfkill_set_hw_state(struct iwl_priv *priv)
{
if (!priv->rfkill_mngr.rfkill)
if (!priv->rfkill)
return;
if (!iwl_is_rfkill(priv))
priv->rfkill_mngr.rfkill->state = RFKILL_STATE_ON;
if (iwl_is_rfkill_hw(priv)) {
rfkill_force_state(priv->rfkill, RFKILL_STATE_HARD_BLOCKED);
return;
}
if (!iwl_is_rfkill_sw(priv))
rfkill_force_state(priv->rfkill, RFKILL_STATE_UNBLOCKED);
else
priv->rfkill_mngr.rfkill->state = RFKILL_STATE_OFF;
rfkill_force_state(priv->rfkill, RFKILL_STATE_SOFT_BLOCKED);
}
EXPORT_SYMBOL(iwl_rfkill_set_hw_state);
......@@ -33,9 +33,6 @@ struct iwl_priv;
#include <linux/rfkill.h>
#ifdef CONFIG_IWLWIFI_RFKILL
struct iwl_rfkill_mngr {
struct rfkill *rfkill;
};
void iwl_rfkill_set_hw_state(struct iwl_priv *priv);
void iwl_rfkill_unregister(struct iwl_priv *priv);
......
......@@ -1493,7 +1493,7 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
}
EXPORT_SYMBOL(iwl_rx_reply_compressed_ba);
#ifdef CONFIG_IWLWIF_DEBUG
#ifdef CONFIG_IWLWIFI_DEBUG
#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
const char *iwl_get_tx_fail_reason(u32 status)
......
......@@ -537,10 +537,20 @@ static inline int iwl3945_is_init(struct iwl3945_priv *priv)
return test_bit(STATUS_INIT, &priv->status);
}
static inline int iwl3945_is_rfkill_sw(struct iwl3945_priv *priv)
{
return test_bit(STATUS_RF_KILL_SW, &priv->status);
}
static inline int iwl3945_is_rfkill_hw(struct iwl3945_priv *priv)
{
return test_bit(STATUS_RF_KILL_HW, &priv->status);
}
static inline int iwl3945_is_rfkill(struct iwl3945_priv *priv)
{
return test_bit(STATUS_RF_KILL_HW, &priv->status) ||
test_bit(STATUS_RF_KILL_SW, &priv->status);
return iwl3945_is_rfkill_hw(priv) ||
iwl3945_is_rfkill_sw(priv);
}
static inline int iwl3945_is_ready_rf(struct iwl3945_priv *priv)
......@@ -6013,12 +6023,11 @@ static int __iwl3945_up(struct iwl3945_priv *priv)
else {
set_bit(STATUS_RF_KILL_HW, &priv->status);
if (!test_bit(STATUS_IN_SUSPEND, &priv->status)) {
iwl3945_rfkill_set_hw_state(priv);
IWL_WARNING("Radio disabled by HW RF Kill switch\n");
return -ENODEV;
}
}
iwl3945_rfkill_set_hw_state(priv);
iwl3945_write32(priv, CSR_INT, 0xFFFFFFFF);
rc = iwl3945_hw_nic_init(priv);
......@@ -6143,8 +6152,8 @@ static void iwl3945_bg_rf_kill(struct work_struct *work)
"wireless networking to work.\n");
}
iwl3945_rfkill_set_hw_state(priv);
mutex_unlock(&priv->mutex);
iwl3945_rfkill_set_hw_state(priv);
}
static void iwl3945_bg_set_monitor(struct work_struct *work)
......@@ -6398,6 +6407,7 @@ static void iwl3945_bg_up(struct work_struct *data)
mutex_lock(&priv->mutex);
__iwl3945_up(priv);
mutex_unlock(&priv->mutex);
iwl3945_rfkill_set_hw_state(priv);
}
static void iwl3945_bg_restart(struct work_struct *data)
......@@ -6618,6 +6628,8 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw)
mutex_unlock(&priv->mutex);
iwl3945_rfkill_set_hw_state(priv);
if (ret)
goto out_release_irq;
......@@ -8276,14 +8288,14 @@ static int iwl3945_pci_resume(struct pci_dev *pdev)
#endif /* CONFIG_PM */
/*************** RFKILL FUNCTIONS **********/
#ifdef CONFIG_IWLWIFI_RFKILL
#ifdef CONFIG_IWL3945_RFKILL
/* software rf-kill from user */
static int iwl3945_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
{
struct iwl3945_priv *priv = data;
int err = 0;
if (!priv->rfkill_mngr.rfkill)
if (!priv->rfkill)
return 0;
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
......@@ -8294,20 +8306,20 @@ static int iwl3945_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
switch (state) {
case RFKILL_STATE_UNBLOCKED:
iwl3945_radio_kill_sw(priv, 0);
/* if HW rf-kill is set dont allow ON state */
if (iwl3945_is_rfkill(priv))
if (iwl3945_is_rfkill_hw(priv)) {
err = -EBUSY;
goto out_unlock;
}
iwl3945_radio_kill_sw(priv, 0);
break;
case RFKILL_STATE_SOFT_BLOCKED:
iwl3945_radio_kill_sw(priv, 1);
if (!iwl3945_is_rfkill(priv))
err = -EBUSY;
break;
default:
IWL_WARNING("we recieved unexpected RFKILL state %d\n", state);
break;
}
out_unlock:
mutex_unlock(&priv->mutex);
return err;
......@@ -8321,64 +8333,35 @@ int iwl3945_rfkill_init(struct iwl3945_priv *priv)
BUG_ON(device == NULL);
IWL_DEBUG_RF_KILL("Initializing RFKILL.\n");
priv->rfkill_mngr.rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN);
if (!priv->rfkill_mngr.rfkill) {
priv->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN);
if (!priv->rfkill) {
IWL_ERROR("Unable to allocate rfkill device.\n");
ret = -ENOMEM;
goto error;
}
priv->rfkill_mngr.rfkill->name = priv->cfg->name;
priv->rfkill_mngr.rfkill->data = priv;
priv->rfkill_mngr.rfkill->state = RFKILL_STATE_ON;
priv->rfkill_mngr.rfkill->toggle_radio = iwl3945_rfkill_soft_rf_kill;
priv->rfkill_mngr.rfkill->user_claim_unsupported = 1;
priv->rfkill_mngr.rfkill->dev.class->suspend = NULL;
priv->rfkill_mngr.rfkill->dev.class->resume = NULL;
priv->rfkill->name = priv->cfg->name;
priv->rfkill->data = priv;
priv->rfkill->state = RFKILL_STATE_UNBLOCKED;
priv->rfkill->toggle_radio = iwl3945_rfkill_soft_rf_kill;
priv->rfkill->user_claim_unsupported = 1;
priv->rfkill_mngr.input_dev = input_allocate_device();
if (!priv->rfkill_mngr.input_dev) {
IWL_ERROR("Unable to allocate rfkill input device.\n");
ret = -ENOMEM;
goto freed_rfkill;
}
priv->rfkill->dev.class->suspend = NULL;
priv->rfkill->dev.class->resume = NULL;
priv->rfkill_mngr.input_dev->name = priv->cfg->name;
priv->rfkill_mngr.input_dev->phys = wiphy_name(priv->hw->wiphy);
priv->rfkill_mngr.input_dev->id.bustype = BUS_HOST;
priv->rfkill_mngr.input_dev->id.vendor = priv->pci_dev->vendor;
priv->rfkill_mngr.input_dev->dev.parent = device;
priv->rfkill_mngr.input_dev->evbit[0] = BIT(EV_KEY);
set_bit(KEY_WLAN, priv->rfkill_mngr.input_dev->keybit);
ret = rfkill_register(priv->rfkill_mngr.rfkill);
ret = rfkill_register(priv->rfkill);
if (ret) {
IWL_ERROR("Unable to register rfkill: %d\n", ret);
goto free_input_dev;
}
ret = input_register_device(priv->rfkill_mngr.input_dev);
if (ret) {
IWL_ERROR("Unable to register rfkill input device: %d\n", ret);
goto unregister_rfkill;
goto freed_rfkill;
}
IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
return ret;
unregister_rfkill:
rfkill_unregister(priv->rfkill_mngr.rfkill);
priv->rfkill_mngr.rfkill = NULL;
free_input_dev:
input_free_device(priv->rfkill_mngr.input_dev);
priv->rfkill_mngr.input_dev = NULL;
freed_rfkill:
if (priv->rfkill_mngr.rfkill != NULL)
rfkill_free(priv->rfkill_mngr.rfkill);
priv->rfkill_mngr.rfkill = NULL;
if (priv->rfkill != NULL)
rfkill_free(priv->rfkill);
priv->rfkill = NULL;
error:
IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
......@@ -8387,28 +8370,28 @@ error:
void iwl3945_rfkill_unregister(struct iwl3945_priv *priv)
{
if (priv->rfkill)
rfkill_unregister(priv->rfkill);
if (priv->rfkill_mngr.input_dev)
input_unregister_device(priv->rfkill_mngr.input_dev);
if (priv->rfkill_mngr.rfkill)
rfkill_unregister(priv->rfkill_mngr.rfkill);
priv->rfkill_mngr.input_dev = NULL;
priv->rfkill_mngr.rfkill = NULL;
priv->rfkill = NULL;
}
/* set rf-kill to the right state. */
void iwl3945_rfkill_set_hw_state(struct iwl3945_priv *priv)
{
if (!priv->rfkill_mngr.rfkill)
if (!priv->rfkill)
return;
if (iwl3945_is_rfkill_hw(priv)) {
rfkill_force_state(priv->rfkill, RFKILL_STATE_HARD_BLOCKED);
return;
}
if (!iwl3945_is_rfkill(priv))
priv->rfkill_mngr.rfkill->state = RFKILL_STATE_ON;
if (!iwl3945_is_rfkill_sw(priv))
rfkill_force_state(priv->rfkill, RFKILL_STATE_UNBLOCKED);
else
priv->rfkill_mngr.rfkill->state = RFKILL_STATE_OFF;
rfkill_force_state(priv->rfkill, RFKILL_STATE_SOFT_BLOCKED);
}
#endif
......
......@@ -2187,13 +2187,11 @@ static int __iwl4965_up(stru