drivers/net/wireless/ralink/rt2x00/rt2x00mac.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/ralink/rt2x00/rt2x00mac.c
Extension
.c
Size
23986 bytes
Lines
841
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (rt2x00queue_available(queue) <= 1) {
			/*
			 * Recheck for full queue under lock to avoid race
			 * conditions with rt2x00lib_txdone().
			 */
			spin_lock(&queue->tx_lock);
			if (rt2x00queue_threshold(queue))
				rt2x00queue_pause_queue(queue);
			spin_unlock(&queue->tx_lock);

			goto exit_free_skb;
		}

		if (rt2x00mac_tx_rts_cts(rt2x00dev, queue, skb))
			goto exit_free_skb;
	}

	if (unlikely(rt2x00queue_write_tx_frame(queue, skb, control->sta, false)))
		goto exit_free_skb;

	return;

 exit_free_skb:
	ieee80211_free_txskb(hw, skb);
}
EXPORT_SYMBOL_GPL(rt2x00mac_tx);

int rt2x00mac_start(struct ieee80211_hw *hw)
{
	struct rt2x00_dev *rt2x00dev = hw->priv;

	if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
		return 0;

	if (test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags)) {
		/*
		 * This is special case for ieee80211_restart_hw(), otherwise
		 * mac80211 never call start() two times in row without stop();
		 */
		set_bit(DEVICE_STATE_RESET, &rt2x00dev->flags);
		rt2x00dev->ops->lib->pre_reset_hw(rt2x00dev);
		rt2x00lib_stop(rt2x00dev);
	}
	return rt2x00lib_start(rt2x00dev);
}
EXPORT_SYMBOL_GPL(rt2x00mac_start);

void rt2x00mac_stop(struct ieee80211_hw *hw, bool suspend)
{
	struct rt2x00_dev *rt2x00dev = hw->priv;

	if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
		return;

	rt2x00lib_stop(rt2x00dev);
}
EXPORT_SYMBOL_GPL(rt2x00mac_stop);

void
rt2x00mac_reconfig_complete(struct ieee80211_hw *hw,
			    enum ieee80211_reconfig_type reconfig_type)
{
	struct rt2x00_dev *rt2x00dev = hw->priv;

	if (reconfig_type == IEEE80211_RECONFIG_TYPE_RESTART)
		clear_bit(DEVICE_STATE_RESET, &rt2x00dev->flags);
}
EXPORT_SYMBOL_GPL(rt2x00mac_reconfig_complete);

int rt2x00mac_add_interface(struct ieee80211_hw *hw,
			    struct ieee80211_vif *vif)
{
	struct rt2x00_dev *rt2x00dev = hw->priv;
	struct rt2x00_intf *intf = vif_to_intf(vif);
	struct data_queue *queue = rt2x00dev->bcn;
	struct queue_entry *entry = NULL;
	unsigned int i;

	/*
	 * Don't allow interfaces to be added
	 * the device has disappeared.
	 */
	if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) ||
	    !test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags))
		return -ENODEV;

	/*
	 * Loop through all beacon queues to find a free
	 * entry. Since there are as much beacon entries
	 * as the maximum interfaces, this search shouldn't

Annotation

Implementation Notes