aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/wireless/rt2x00/rt2x00dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00dev.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c123
1 files changed, 76 insertions, 47 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 189744db65e..4fa43a2eeb7 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -14,9 +14,7 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the
- Free Software Foundation, Inc.,
- 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
/*
@@ -88,7 +86,7 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
rt2x00queue_start_queues(rt2x00dev);
rt2x00link_start_tuner(rt2x00dev);
rt2x00link_start_agc(rt2x00dev);
- if (test_bit(CAPABILITY_VCO_RECALIBRATION, &rt2x00dev->cap_flags))
+ if (rt2x00_has_cap_vco_recalibration(rt2x00dev))
rt2x00link_start_vcocal(rt2x00dev);
/*
@@ -113,7 +111,7 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev)
* Stop all queues
*/
rt2x00link_stop_agc(rt2x00dev);
- if (test_bit(CAPABILITY_VCO_RECALIBRATION, &rt2x00dev->cap_flags))
+ if (rt2x00_has_cap_vco_recalibration(rt2x00dev))
rt2x00link_stop_vcocal(rt2x00dev);
rt2x00link_stop_tuner(rt2x00dev);
rt2x00queue_stop_queues(rt2x00dev);
@@ -171,7 +169,7 @@ static void rt2x00lib_autowakeup(struct work_struct *work)
return;
if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE))
- ERROR(rt2x00dev, "Device failed to wakeup.\n");
+ rt2x00_err(rt2x00dev, "Device failed to wakeup\n");
clear_bit(CONFIG_POWERSAVING, &rt2x00dev->flags);
}
@@ -181,6 +179,7 @@ static void rt2x00lib_autowakeup(struct work_struct *work)
static void rt2x00lib_bc_buffer_iter(void *data, u8 *mac,
struct ieee80211_vif *vif)
{
+ struct ieee80211_tx_control control = {};
struct rt2x00_dev *rt2x00dev = data;
struct sk_buff *skb;
@@ -195,7 +194,7 @@ static void rt2x00lib_bc_buffer_iter(void *data, u8 *mac,
*/
skb = ieee80211_get_buffered_bc(rt2x00dev->hw, vif);
while (skb) {
- rt2x00mac_tx(rt2x00dev->hw, NULL, skb);
+ rt2x00mac_tx(rt2x00dev->hw, &control, skb);
skb = ieee80211_get_buffered_bc(rt2x00dev->hw, vif);
}
}
@@ -234,7 +233,7 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev)
* here as they will fetch the next beacon directly prior to
* transmission.
*/
- if (test_bit(CAPABILITY_PRE_TBTT_INTERRUPT, &rt2x00dev->cap_flags))
+ if (rt2x00_has_cap_pre_tbtt_interrupt(rt2x00dev))
return;
/* fetch next beacon */
@@ -334,7 +333,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
/*
* Remove the extra tx headroom from the skb.
*/
- skb_pull(entry->skb, rt2x00dev->ops->extra_tx_headroom);
+ skb_pull(entry->skb, rt2x00dev->extra_tx_headroom);
/*
* Signal that the TX descriptor is no longer in the skb.
@@ -358,7 +357,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
* mac80211 will expect the same data to be present it the
* frame as it was passed to us.
*/
- if (test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags))
+ if (rt2x00_has_cap_hw_crypto(rt2x00dev))
rt2x00crypto_tx_insert_iv(entry->skb, header_length);
/*
@@ -566,10 +565,10 @@ static void rt2x00lib_rxdone_check_ba(struct rt2x00_dev *rt2x00dev,
#undef TID_CHECK
- if (compare_ether_addr(ba->ra, entry->ta))
+ if (!ether_addr_equal_64bits(ba->ra, entry->ta))
continue;
- if (compare_ether_addr(ba->ta, entry->ra))
+ if (!ether_addr_equal_64bits(ba->ta, entry->ra))
continue;
/* Mark BAR since we received the according BA */
@@ -673,9 +672,8 @@ static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev,
break;
}
- WARNING(rt2x00dev, "Frame received with unrecognized signal, "
- "mode=0x%.4x, signal=0x%.4x, type=%d.\n",
- rxdesc->rate_mode, signal, type);
+ rt2x00_warn(rt2x00dev, "Frame received with unrecognized signal, mode=0x%.4x, signal=0x%.4x, type=%d\n",
+ rxdesc->rate_mode, signal, type);
return 0;
}
@@ -720,8 +718,8 @@ void rt2x00lib_rxdone(struct queue_entry *entry, gfp_t gfp)
*/
if (unlikely(rxdesc.size == 0 ||
rxdesc.size > entry->queue->data_size)) {
- ERROR(rt2x00dev, "Wrong frame size %d max %d.\n",
- rxdesc.size, entry->queue->data_size);
+ rt2x00_err(rt2x00dev, "Wrong frame size %d max %d\n",
+ rxdesc.size, entry->queue->data_size);
dev_kfree_skb(entry->skb);
goto renew_skb;
}
@@ -1006,7 +1004,7 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev,
exit_free_channels:
kfree(channels);
- ERROR(rt2x00dev, "Allocation ieee80211 modes failed.\n");
+ rt2x00_err(rt2x00dev, "Allocation ieee80211 modes failed\n");
return -ENOMEM;
}
@@ -1050,7 +1048,7 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
*/
rt2x00dev->hw->extra_tx_headroom =
max_t(unsigned int, IEEE80211_TX_STATUS_HEADROOM,
- rt2x00dev->ops->extra_tx_headroom);
+ rt2x00dev->extra_tx_headroom);
/*
* Take TX headroom required for alignment into account.
@@ -1078,7 +1076,7 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
*/
int kfifo_size =
roundup_pow_of_two(rt2x00dev->ops->tx_queues *
- rt2x00dev->ops->tx->entry_num *
+ rt2x00dev->tx->limit *
sizeof(u32));
status = kfifo_alloc(&rt2x00dev->txstatus_fifo, kfifo_size,
@@ -1128,9 +1126,10 @@ static void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev)
return;
/*
- * Unregister extra components.
+ * Stop rfkill polling.
*/
- rt2x00rfkill_unregister(rt2x00dev);
+ if (test_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags))
+ rt2x00rfkill_unregister(rt2x00dev);
/*
* Allow the HW to uninitialize.
@@ -1168,6 +1167,12 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev)
set_bit(DEVICE_STATE_INITIALIZED, &rt2x00dev->flags);
+ /*
+ * Start rfkill polling.
+ */
+ if (test_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags))
+ rt2x00rfkill_register(rt2x00dev);
+
return 0;
}
@@ -1257,6 +1262,17 @@ static inline void rt2x00lib_set_if_combinations(struct rt2x00_dev *rt2x00dev)
rt2x00dev->hw->wiphy->n_iface_combinations = 1;
}
+static unsigned int rt2x00dev_extra_tx_headroom(struct rt2x00_dev *rt2x00dev)
+{
+ if (WARN_ON(!rt2x00dev->tx))
+ return 0;
+
+ if (rt2x00_is_usb(rt2x00dev))
+ return rt2x00dev->tx[0].winfo_size + rt2x00dev->tx[0].desc_size;
+
+ return rt2x00dev->tx[0].winfo_size;
+}
+
/*
* driver allocation handlers.
*/
@@ -1302,27 +1318,10 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
(rt2x00dev->ops->max_ap_intf - 1);
/*
- * Determine which operating modes are supported, all modes
- * which require beaconing, depend on the availability of
- * beacon entries.
- */
- rt2x00dev->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
- if (rt2x00dev->ops->bcn->entry_num > 0)
- rt2x00dev->hw->wiphy->interface_modes |=
- BIT(NL80211_IFTYPE_ADHOC) |
- BIT(NL80211_IFTYPE_AP) |
-#ifdef CONFIG_MAC80211_MESH
- BIT(NL80211_IFTYPE_MESH_POINT) |
-#endif
- BIT(NL80211_IFTYPE_WDS);
-
- rt2x00dev->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
-
- /*
* Initialize work.
*/
rt2x00dev->workqueue =
- alloc_ordered_workqueue(wiphy_name(rt2x00dev->hw->wiphy), 0);
+ alloc_ordered_workqueue("%s", 0, wiphy_name(rt2x00dev->hw->wiphy));
if (!rt2x00dev->workqueue) {
retval = -ENOMEM;
goto exit;
@@ -1337,7 +1336,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
*/
retval = rt2x00dev->ops->lib->probe_hw(rt2x00dev);
if (retval) {
- ERROR(rt2x00dev, "Failed to allocate device.\n");
+ rt2x00_err(rt2x00dev, "Failed to allocate device\n");
goto exit;
}
@@ -1348,12 +1347,32 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
if (retval)
goto exit;
+ /* Cache TX headroom value */
+ rt2x00dev->extra_tx_headroom = rt2x00dev_extra_tx_headroom(rt2x00dev);
+
+ /*
+ * Determine which operating modes are supported, all modes
+ * which require beaconing, depend on the availability of
+ * beacon entries.
+ */
+ rt2x00dev->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+ if (rt2x00dev->bcn->limit > 0)
+ rt2x00dev->hw->wiphy->interface_modes |=
+ BIT(NL80211_IFTYPE_ADHOC) |
+ BIT(NL80211_IFTYPE_AP) |
+#ifdef CONFIG_MAC80211_MESH
+ BIT(NL80211_IFTYPE_MESH_POINT) |
+#endif
+ BIT(NL80211_IFTYPE_WDS);
+
+ rt2x00dev->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
+
/*
* Initialize ieee80211 structure.
*/
retval = rt2x00lib_probe_hw(rt2x00dev);
if (retval) {
- ERROR(rt2x00dev, "Failed to initialize hw.\n");
+ rt2x00_err(rt2x00dev, "Failed to initialize hw\n");
goto exit;
}
@@ -1363,7 +1382,12 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
rt2x00link_register(rt2x00dev);
rt2x00leds_register(rt2x00dev);
rt2x00debug_register(rt2x00dev);
- rt2x00rfkill_register(rt2x00dev);
+
+ /*
+ * Start rfkill polling.
+ */
+ if (!test_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags))
+ rt2x00rfkill_register(rt2x00dev);
return 0;
@@ -1379,6 +1403,12 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
/*
+ * Stop rfkill polling.
+ */
+ if (!test_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags))
+ rt2x00rfkill_unregister(rt2x00dev);
+
+ /*
* Disable radio.
*/
rt2x00lib_disable_radio(rt2x00dev);
@@ -1451,7 +1481,7 @@ EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev);
#ifdef CONFIG_PM
int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state)
{
- DEBUG(rt2x00dev, "Going to sleep.\n");
+ rt2x00_dbg(rt2x00dev, "Going to sleep\n");
/*
* Prevent mac80211 from accessing driver while suspended.
@@ -1482,8 +1512,7 @@ int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state)
* device is as good as disabled.
*/
if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_SLEEP))
- WARNING(rt2x00dev, "Device failed to enter sleep state, "
- "continue suspending.\n");
+ rt2x00_warn(rt2x00dev, "Device failed to enter sleep state, continue suspending\n");
return 0;
}
@@ -1491,7 +1520,7 @@ EXPORT_SYMBOL_GPL(rt2x00lib_suspend);
int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
{
- DEBUG(rt2x00dev, "Waking up.\n");
+ rt2x00_dbg(rt2x00dev, "Waking up\n");
/*
* Restore/enable extra components.