Commit d5dc056c authored by David S. Miller's avatar David S. Miller
parents 00ae7028 73714004
...@@ -94,6 +94,8 @@ static struct usb_device_id ar9170_usb_ids[] = { ...@@ -94,6 +94,8 @@ static struct usb_device_id ar9170_usb_ids[] = {
{ USB_DEVICE(0x04bb, 0x093f) }, { USB_DEVICE(0x04bb, 0x093f) },
/* AVM FRITZ!WLAN USB Stick N */ /* AVM FRITZ!WLAN USB Stick N */
{ USB_DEVICE(0x057C, 0x8401) }, { USB_DEVICE(0x057C, 0x8401) },
/* NEC WL300NU-G */
{ USB_DEVICE(0x0409, 0x0249) },
/* AVM FRITZ!WLAN USB Stick N 2.4 */ /* AVM FRITZ!WLAN USB Stick N 2.4 */
{ USB_DEVICE(0x057C, 0x8402), .driver_info = AR9170_REQ_FW1_ONLY }, { USB_DEVICE(0x057C, 0x8402), .driver_info = AR9170_REQ_FW1_ONLY },
...@@ -416,7 +418,7 @@ static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd, ...@@ -416,7 +418,7 @@ static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd,
spin_unlock_irqrestore(&aru->common.cmdlock, flags); spin_unlock_irqrestore(&aru->common.cmdlock, flags);
usb_fill_int_urb(urb, aru->udev, usb_fill_int_urb(urb, aru->udev,
usb_sndbulkpipe(aru->udev, AR9170_EP_CMD), usb_sndintpipe(aru->udev, AR9170_EP_CMD),
aru->common.cmdbuf, plen + 4, aru->common.cmdbuf, plen + 4,
ar9170_usb_tx_urb_complete, NULL, 1); ar9170_usb_tx_urb_complete, NULL, 1);
......
...@@ -2041,16 +2041,14 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, ...@@ -2041,16 +2041,14 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
tx_resp->failure_frame); tx_resp->failure_frame);
freed = iwl_tx_queue_reclaim(priv, txq_id, index); freed = iwl_tx_queue_reclaim(priv, txq_id, index);
if (qc && likely(sta_id != IWL_INVALID_STATION)) iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
if (priv->mac80211_registered && if (priv->mac80211_registered &&
(iwl_queue_space(&txq->q) > txq->q.low_mark)) (iwl_queue_space(&txq->q) > txq->q.low_mark))
iwl_wake_queue(priv, txq_id); iwl_wake_queue(priv, txq_id);
} }
if (qc && likely(sta_id != IWL_INVALID_STATION)) iwl_txq_check_empty(priv, sta_id, tid, txq_id);
iwl_txq_check_empty(priv, sta_id, tid, txq_id);
if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n"); IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n");
......
...@@ -1258,7 +1258,15 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) ...@@ -1258,7 +1258,15 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
/* Ack/clear/reset pending uCode interrupts. /* Ack/clear/reset pending uCode interrupts.
* Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS, * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS,
*/ */
iwl_write32(priv, CSR_INT, priv->inta); /* There is a hardware bug in the interrupt mask function that some
* interrupts (i.e. CSR_INT_BIT_SCD) can still be generated even if
* they are disabled in the CSR_INT_MASK register. Furthermore the
* ICT interrupt handling mechanism has another bug that might cause
* these unmasked interrupts fail to be detected. We workaround the
* hardware bugs here by ACKing all the possible interrupts so that
* interrupt coalescing can still be achieved.
*/
iwl_write32(priv, CSR_INT, priv->inta | ~priv->inta_mask);
inta = priv->inta; inta = priv->inta;
...@@ -2644,7 +2652,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv) ...@@ -2644,7 +2652,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv)
BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_ADHOC); BIT(NL80211_IFTYPE_ADHOC);
hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY | hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
WIPHY_FLAG_DISABLE_BEACON_HINTS; WIPHY_FLAG_DISABLE_BEACON_HINTS;
/* /*
......
...@@ -1955,7 +1955,7 @@ static void iwl3945_init_hw_rates(struct iwl_priv *priv, ...@@ -1955,7 +1955,7 @@ static void iwl3945_init_hw_rates(struct iwl_priv *priv,
{ {
int i; int i;
for (i = 0; i < IWL_RATE_COUNT; i++) { for (i = 0; i < IWL_RATE_COUNT_LEGACY; i++) {
rates[i].bitrate = iwl3945_rates[i].ieee * 5; rates[i].bitrate = iwl3945_rates[i].ieee * 5;
rates[i].hw_value = i; /* Rate scaling will work on indexes */ rates[i].hw_value = i; /* Rate scaling will work on indexes */
rates[i].hw_value_short = i; rates[i].hw_value_short = i;
...@@ -3921,7 +3921,7 @@ static int iwl3945_setup_mac(struct iwl_priv *priv) ...@@ -3921,7 +3921,7 @@ static int iwl3945_setup_mac(struct iwl_priv *priv)
BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_ADHOC); BIT(NL80211_IFTYPE_ADHOC);
hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY | hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
WIPHY_FLAG_DISABLE_BEACON_HINTS; WIPHY_FLAG_DISABLE_BEACON_HINTS;
hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945; hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945;
......
...@@ -172,6 +172,8 @@ int lbs_cfg_register(struct lbs_private *priv) ...@@ -172,6 +172,8 @@ int lbs_cfg_register(struct lbs_private *priv)
if (ret < 0) if (ret < 0)
lbs_pr_err("cannot register wiphy device\n"); lbs_pr_err("cannot register wiphy device\n");
priv->wiphy_registered = true;
ret = register_netdev(priv->dev); ret = register_netdev(priv->dev);
if (ret) if (ret)
lbs_pr_err("cannot register network device\n"); lbs_pr_err("cannot register network device\n");
...@@ -190,9 +192,11 @@ void lbs_cfg_free(struct lbs_private *priv) ...@@ -190,9 +192,11 @@ void lbs_cfg_free(struct lbs_private *priv)
if (!wdev) if (!wdev)
return; return;
if (wdev->wiphy) { if (priv->wiphy_registered)
wiphy_unregister(wdev->wiphy); wiphy_unregister(wdev->wiphy);
if (wdev->wiphy)
wiphy_free(wdev->wiphy); wiphy_free(wdev->wiphy);
}
kfree(wdev); kfree(wdev);
} }
...@@ -36,6 +36,7 @@ struct lbs_private { ...@@ -36,6 +36,7 @@ struct lbs_private {
/* CFG80211 */ /* CFG80211 */
struct wireless_dev *wdev; struct wireless_dev *wdev;
bool wiphy_registered;
/* Mesh */ /* Mesh */
struct net_device *mesh_dev; /* Virtual device */ struct net_device *mesh_dev; /* Virtual device */
......
...@@ -3851,6 +3851,7 @@ MODULE_FIRMWARE("mwl8k/helper_8366.fw"); ...@@ -3851,6 +3851,7 @@ MODULE_FIRMWARE("mwl8k/helper_8366.fw");
MODULE_FIRMWARE("mwl8k/fmimage_8366.fw"); MODULE_FIRMWARE("mwl8k/fmimage_8366.fw");
static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = { static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = {
{ PCI_VDEVICE(MARVELL, 0x2a0a), .driver_data = MWL8363, },
{ PCI_VDEVICE(MARVELL, 0x2a0c), .driver_data = MWL8363, }, { PCI_VDEVICE(MARVELL, 0x2a0c), .driver_data = MWL8363, },
{ PCI_VDEVICE(MARVELL, 0x2a24), .driver_data = MWL8363, }, { PCI_VDEVICE(MARVELL, 0x2a24), .driver_data = MWL8363, },
{ PCI_VDEVICE(MARVELL, 0x2a2b), .driver_data = MWL8687, }, { PCI_VDEVICE(MARVELL, 0x2a2b), .driver_data = MWL8687, },
......
...@@ -35,6 +35,7 @@ MODULE_FIRMWARE("isl3887usb"); ...@@ -35,6 +35,7 @@ MODULE_FIRMWARE("isl3887usb");
static struct usb_device_id p54u_table[] __devinitdata = { static struct usb_device_id p54u_table[] __devinitdata = {
/* Version 1 devices (pci chip + net2280) */ /* Version 1 devices (pci chip + net2280) */
{USB_DEVICE(0x0506, 0x0a11)}, /* 3COM 3CRWE254G72 */ {USB_DEVICE(0x0506, 0x0a11)}, /* 3COM 3CRWE254G72 */
{USB_DEVICE(0x06b9, 0x0120)}, /* Thomson SpeedTouch 120g */
{USB_DEVICE(0x0707, 0xee06)}, /* SMC 2862W-G */ {USB_DEVICE(0x0707, 0xee06)}, /* SMC 2862W-G */
{USB_DEVICE(0x07aa, 0x001c)}, /* Corega CG-WLUSB2GT */ {USB_DEVICE(0x07aa, 0x001c)}, /* Corega CG-WLUSB2GT */
{USB_DEVICE(0x083a, 0x4501)}, /* Accton 802.11g WN4501 USB */ {USB_DEVICE(0x083a, 0x4501)}, /* Accton 802.11g WN4501 USB */
......
...@@ -1642,6 +1642,11 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) ...@@ -1642,6 +1642,11 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
char *tx_power; char *tx_power;
unsigned int i; unsigned int i;
/*
* Disable powersaving as default.
*/
rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
/* /*
* Initialize all hw fields. * Initialize all hw fields.
*/ */
......
...@@ -812,9 +812,9 @@ static void rt2800_config_channel_rt3x(struct rt2x00_dev *rt2x00dev, ...@@ -812,9 +812,9 @@ static void rt2800_config_channel_rt3x(struct rt2x00_dev *rt2x00dev,
rt2800_rfcsr_write(rt2x00dev, 24, rt2800_rfcsr_write(rt2x00dev, 24,
rt2x00dev->calibration[conf_is_ht40(conf)]); rt2x00dev->calibration[conf_is_ht40(conf)]);
rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr); rt2800_rfcsr_read(rt2x00dev, 7, &rfcsr);
rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1); rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1);
rt2800_rfcsr_write(rt2x00dev, 23, rfcsr); rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
} }
static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
......
...@@ -391,7 +391,7 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata, ...@@ -391,7 +391,7 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
if (SN_GT(mpath->sn, orig_sn) || if (SN_GT(mpath->sn, orig_sn) ||
(mpath->sn == orig_sn && (mpath->sn == orig_sn &&
action == MPATH_PREQ && action == MPATH_PREQ &&
new_metric > mpath->metric)) { new_metric >= mpath->metric)) {
process = false; process = false;
fresh_info = false; fresh_info = false;
} }
...@@ -611,7 +611,7 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata, ...@@ -611,7 +611,7 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
mesh_path_sel_frame_tx(MPATH_PREP, flags, orig_addr, mesh_path_sel_frame_tx(MPATH_PREP, flags, orig_addr,
cpu_to_le32(orig_sn), 0, target_addr, cpu_to_le32(orig_sn), 0, target_addr,
cpu_to_le32(target_sn), mpath->next_hop->sta.addr, hopcount, cpu_to_le32(target_sn), next_hop, hopcount,
ttl, cpu_to_le32(lifetime), cpu_to_le32(metric), ttl, cpu_to_le32(lifetime), cpu_to_le32(metric),
0, sdata); 0, sdata);
rcu_read_unlock(); rcu_read_unlock();
......
...@@ -1991,6 +1991,7 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local, ...@@ -1991,6 +1991,7 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local,
void ieee80211_tx_pending(unsigned long data) void ieee80211_tx_pending(unsigned long data)
{ {
struct ieee80211_local *local = (struct ieee80211_local *)data; struct ieee80211_local *local = (struct ieee80211_local *)data;
struct ieee80211_sub_if_data *sdata;
unsigned long flags; unsigned long flags;
int i; int i;
bool txok; bool txok;
...@@ -2029,6 +2030,11 @@ void ieee80211_tx_pending(unsigned long data) ...@@ -2029,6 +2030,11 @@ void ieee80211_tx_pending(unsigned long data)
if (!txok) if (!txok)
break; break;
} }
if (skb_queue_empty(&local->pending[i]))
list_for_each_entry_rcu(sdata, &local->interfaces, list)
netif_tx_wake_queue(
netdev_get_tx_queue(sdata->dev, i));
} }
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
......
...@@ -279,13 +279,13 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue, ...@@ -279,13 +279,13 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
/* someone still has this queue stopped */ /* someone still has this queue stopped */
return; return;
if (!skb_queue_empty(&local->pending[queue])) if (skb_queue_empty(&local->pending[queue])) {
rcu_read_lock();
list_for_each_entry_rcu(sdata, &local->interfaces, list)
netif_tx_wake_queue(netdev_get_tx_queue(sdata->dev, queue));
rcu_read_unlock();
} else
tasklet_schedule(&local->tx_pending_tasklet); tasklet_schedule(&local->tx_pending_tasklet);
rcu_read_lock();
list_for_each_entry_rcu(sdata, &local->interfaces, list)
netif_tx_wake_queue(netdev_get_tx_queue(sdata->dev, queue));
rcu_read_unlock();
} }
void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
...@@ -1097,9 +1097,9 @@ int ieee80211_reconfig(struct ieee80211_local *local) ...@@ -1097,9 +1097,9 @@ int ieee80211_reconfig(struct ieee80211_local *local)
*/ */
res = drv_start(local); res = drv_start(local);
if (res) { if (res) {
WARN(local->suspended, "Harware became unavailable " WARN(local->suspended, "Hardware became unavailable "
"upon resume. This is could be a software issue" "upon resume. This could be a software issue "
"prior to suspend or a hardware issue\n"); "prior to suspend or a hardware issue.\n");
return res; return res;
} }
......
...@@ -324,7 +324,7 @@ struct reg_regdb_search_request { ...@@ -324,7 +324,7 @@ struct reg_regdb_search_request {
}; };
static LIST_HEAD(reg_regdb_search_list); static LIST_HEAD(reg_regdb_search_list);
static DEFINE_SPINLOCK(reg_regdb_search_lock); static DEFINE_MUTEX(reg_regdb_search_mutex);
static void reg_regdb_search(struct work_struct *work) static void reg_regdb_search(struct work_struct *work)
{ {
...@@ -332,7 +332,7 @@ static void reg_regdb_search(struct work_struct *work) ...@@ -332,7 +332,7 @@ static void reg_regdb_search(struct work_struct *work)
const struct ieee80211_regdomain *curdom, *regdom; const struct ieee80211_regdomain *curdom, *regdom;
int i, r; int i, r;
spin_lock(&reg_regdb_search_lock); mutex_lock(&reg_regdb_search_mutex);
while (!list_empty(&reg_regdb_search_list)) { while (!list_empty(&reg_regdb_search_list)) {
request = list_first_entry(&reg_regdb_search_list, request = list_first_entry(&reg_regdb_search_list,
struct reg_regdb_search_request, struct reg_regdb_search_request,
...@@ -346,18 +346,16 @@ static void reg_regdb_search(struct work_struct *work) ...@@ -346,18 +346,16 @@ static void reg_regdb_search(struct work_struct *work)
r = reg_copy_regd(&regdom, curdom); r = reg_copy_regd(&regdom, curdom);
if (r) if (r)
break; break;
spin_unlock(&reg_regdb_search_lock);
mutex_lock(&cfg80211_mutex); mutex_lock(&cfg80211_mutex);
set_regdom(regdom); set_regdom(regdom);
mutex_unlock(&cfg80211_mutex); mutex_unlock(&cfg80211_mutex);
spin_lock(&reg_regdb_search_lock);
break; break;
} }
} }
kfree(request); kfree(request);
} }
spin_unlock(&reg_regdb_search_lock); mutex_unlock(&reg_regdb_search_mutex);
} }
static DECLARE_WORK(reg_regdb_work, reg_regdb_search); static DECLARE_WORK(reg_regdb_work, reg_regdb_search);
...@@ -375,9 +373,9 @@ static void reg_regdb_query(const char *alpha2) ...@@ -375,9 +373,9 @@ static void reg_regdb_query(const char *alpha2)
memcpy(request->alpha2, alpha2, 2); memcpy(request->alpha2, alpha2, 2);
spin_lock(&reg_regdb_search_lock); mutex_lock(&reg_regdb_search_mutex);
list_add_tail(&request->list, &reg_regdb_search_list); list_add_tail(&request->list, &reg_regdb_search_list);
spin_unlock(&reg_regdb_search_lock); mutex_unlock(&reg_regdb_search_mutex);
schedule_work(&reg_regdb_work); schedule_work(&reg_regdb_work);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment