summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ralink/rt2x00/rt2x00dev.c')
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00dev.c91
1 files changed, 48 insertions, 43 deletions
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
index 357c0941aaad..778a478ab53a 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
@@ -1,20 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
Copyright (C) 2010 Willow Garage <http://www.willowgarage.com>
Copyright (C) 2004 - 2010 Ivo van Doorn <IvDoorn@gmail.com>
<http://rt2x00.serialmonkey.com>
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- 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, see <http://www.gnu.org/licenses/>.
*/
/*
@@ -112,6 +101,7 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev)
rt2x00link_stop_tuner(rt2x00dev);
rt2x00queue_stop_queues(rt2x00dev);
rt2x00queue_flush_queues(rt2x00dev, true);
+ rt2x00queue_stop_queue(rt2x00dev->bcn);
/*
* Disable radio.
@@ -205,8 +195,7 @@ static void rt2x00lib_beaconupdate_iter(void *data, u8 *mac,
if (vif->type != NL80211_IFTYPE_AP &&
vif->type != NL80211_IFTYPE_ADHOC &&
- vif->type != NL80211_IFTYPE_MESH_POINT &&
- vif->type != NL80211_IFTYPE_WDS)
+ vif->type != NL80211_IFTYPE_MESH_POINT)
return;
/*
@@ -368,7 +357,7 @@ static void rt2x00lib_fill_tx_status(struct rt2x00_dev *rt2x00dev,
}
/*
- * Every single frame has it's own tx status, hence report
+ * Every single frame has its own tx status, hence report
* every frame as ampdu of size 1.
*
* TODO: if we can find out how many frames were aggregated
@@ -382,9 +371,6 @@ static void rt2x00lib_fill_tx_status(struct rt2x00_dev *rt2x00dev,
IEEE80211_TX_CTL_AMPDU;
tx_info->status.ampdu_len = 1;
tx_info->status.ampdu_ack_len = success ? 1 : 0;
-
- if (!success)
- tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
}
if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
@@ -510,7 +496,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
/*
* If the IV/EIV data was stripped from the frame before it was
* passed to the hardware, we should now reinsert it again because
- * mac80211 will expect the same data to be present it the
+ * mac80211 will expect the same data to be present in the
* frame as it was passed to us.
*/
if (rt2x00_has_cap_hw_crypto(rt2x00dev))
@@ -548,7 +534,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
*/
if (!(skbdesc_flags & SKBDESC_NOT_MAC80211)) {
if (rt2x00_has_cap_flag(rt2x00dev, REQUIRE_TASKLET_CONTEXT))
- ieee80211_tx_status(rt2x00dev->hw, entry->skb);
+ ieee80211_tx_status_skb(rt2x00dev->hw, entry->skb);
else
ieee80211_tx_status_ni(rt2x00dev->hw, entry->skb);
} else {
@@ -693,7 +679,7 @@ static void rt2x00lib_rxdone_check_ps(struct rt2x00_dev *rt2x00dev,
/* Check whenever the PHY can be turned off again. */
/* 1. What about buffered unicast traffic for our AID? */
- cam = ieee80211_check_tim(tim_ie, tim_len, rt2x00dev->aid);
+ cam = ieee80211_check_tim(tim_ie, tim_len, rt2x00dev->aid, false);
/* 2. Maybe the AP wants to send multicast/broadcast data? */
cam |= (tim_ie->bitmap_ctrl & 0x01);
@@ -1002,18 +988,20 @@ static void rt2x00lib_rate(struct ieee80211_rate *entry,
entry->flags |= IEEE80211_RATE_SHORT_PREAMBLE;
}
-void rt2x00lib_set_mac_address(struct rt2x00_dev *rt2x00dev, u8 *eeprom_mac_addr)
+int rt2x00lib_set_mac_address(struct rt2x00_dev *rt2x00dev, u8 *eeprom_mac_addr)
{
- const char *mac_addr;
+ int ret;
- mac_addr = of_get_mac_address(rt2x00dev->dev->of_node);
- if (mac_addr)
- ether_addr_copy(eeprom_mac_addr, mac_addr);
+ ret = of_get_mac_address(rt2x00dev->dev->of_node, eeprom_mac_addr);
+ if (ret == -EPROBE_DEFER)
+ return ret;
if (!is_valid_ether_addr(eeprom_mac_addr)) {
eth_random_addr(eeprom_mac_addr);
rt2x00_eeprom_dbg(rt2x00dev, "MAC: %pM\n", eeprom_mac_addr);
}
+
+ return 0;
}
EXPORT_SYMBOL_GPL(rt2x00lib_set_mac_address);
@@ -1110,8 +1098,22 @@ static void rt2x00lib_remove_hw(struct rt2x00_dev *rt2x00dev)
}
kfree(rt2x00dev->spec.channels_info);
+ kfree(rt2x00dev->chan_survey);
}
+static const struct ieee80211_tpt_blink rt2x00_tpt_blink[] = {
+ { .throughput = 0 * 1024, .blink_time = 334 },
+ { .throughput = 1 * 1024, .blink_time = 260 },
+ { .throughput = 2 * 1024, .blink_time = 220 },
+ { .throughput = 5 * 1024, .blink_time = 190 },
+ { .throughput = 10 * 1024, .blink_time = 170 },
+ { .throughput = 25 * 1024, .blink_time = 150 },
+ { .throughput = 54 * 1024, .blink_time = 130 },
+ { .throughput = 120 * 1024, .blink_time = 110 },
+ { .throughput = 265 * 1024, .blink_time = 80 },
+ { .throughput = 586 * 1024, .blink_time = 50 },
+};
+
static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
{
struct hw_mode_spec *spec = &rt2x00dev->spec;
@@ -1181,9 +1183,8 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
*/
#define RT2X00_TASKLET_INIT(taskletname) \
if (rt2x00dev->ops->lib->taskletname) { \
- tasklet_init(&rt2x00dev->taskletname, \
- rt2x00dev->ops->lib->taskletname, \
- (unsigned long)rt2x00dev); \
+ tasklet_setup(&rt2x00dev->taskletname, \
+ rt2x00dev->ops->lib->taskletname); \
}
RT2X00_TASKLET_INIT(txstatus_tasklet);
@@ -1194,6 +1195,11 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
#undef RT2X00_TASKLET_INIT
+ ieee80211_create_tpt_led_trigger(rt2x00dev->hw,
+ IEEE80211_TPT_LEDTRIG_FL_RADIO,
+ rt2x00_tpt_blink,
+ ARRAY_SIZE(rt2x00_tpt_blink));
+
/*
* Register HW.
*/
@@ -1267,10 +1273,7 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev)
int rt2x00lib_start(struct rt2x00_dev *rt2x00dev)
{
- int retval;
-
- if (test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags))
- return 0;
+ int retval = 0;
/*
* If this is the first interface which is added,
@@ -1278,27 +1281,29 @@ int rt2x00lib_start(struct rt2x00_dev *rt2x00dev)
*/
retval = rt2x00lib_load_firmware(rt2x00dev);
if (retval)
- return retval;
+ goto out;
/*
* Initialize the device.
*/
retval = rt2x00lib_initialize(rt2x00dev);
if (retval)
- return retval;
+ goto out;
rt2x00dev->intf_ap_count = 0;
rt2x00dev->intf_sta_count = 0;
rt2x00dev->intf_associated = 0;
+ rt2x00dev->intf_beaconing = 0;
/* Enable the radio */
retval = rt2x00lib_enable_radio(rt2x00dev);
if (retval)
- return retval;
+ goto out;
set_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags);
- return 0;
+out:
+ return retval;
}
void rt2x00lib_stop(struct rt2x00_dev *rt2x00dev)
@@ -1315,6 +1320,7 @@ void rt2x00lib_stop(struct rt2x00_dev *rt2x00dev)
rt2x00dev->intf_ap_count = 0;
rt2x00dev->intf_sta_count = 0;
rt2x00dev->intf_associated = 0;
+ rt2x00dev->intf_beaconing = 0;
}
static inline void rt2x00lib_set_if_combinations(struct rt2x00_dev *rt2x00dev)
@@ -1391,6 +1397,8 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
mutex_init(&rt2x00dev->conf_mutex);
INIT_LIST_HEAD(&rt2x00dev->bar_list);
spin_lock_init(&rt2x00dev->bar_list_lock);
+ hrtimer_setup(&rt2x00dev->txstatus_timer, hrtimer_dummy_timeout, CLOCK_MONOTONIC,
+ HRTIMER_MODE_REL);
set_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
@@ -1452,9 +1460,6 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
#ifdef CONFIG_MAC80211_MESH
BIT(NL80211_IFTYPE_MESH_POINT) |
#endif
-#ifdef CONFIG_WIRELESS_WDS
- BIT(NL80211_IFTYPE_WDS) |
-#endif
BIT(NL80211_IFTYPE_AP);
rt2x00dev->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
@@ -1515,6 +1520,8 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
cancel_delayed_work_sync(&rt2x00dev->autowakeup_work);
cancel_work_sync(&rt2x00dev->sleep_work);
+ hrtimer_cancel(&rt2x00dev->txstatus_timer);
+
/*
* Kill the tx status tasklet.
*/
@@ -1568,8 +1575,7 @@ EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev);
/*
* Device state handlers
*/
-#ifdef CONFIG_PM
-int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state)
+int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev)
{
rt2x00_dbg(rt2x00dev, "Going to sleep\n");
@@ -1626,7 +1632,6 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
return 0;
}
EXPORT_SYMBOL_GPL(rt2x00lib_resume);
-#endif /* CONFIG_PM */
/*
* rt2x00lib module information.