drivers/net/wireless/st/cw1200/sta.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/st/cw1200/sta.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/st/cw1200/sta.c
Extension
.c
Size
65025 bytes
Lines
2391
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source 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 (priv->link_id_map & BIT(i)) {
				reset.link_id = i;
				wsm_reset(priv, &reset);
				priv->link_id_map &= ~BIT(i);
			}
		}
		memset(priv->link_id_db, 0, sizeof(priv->link_id_db));
		priv->sta_asleep_mask = 0;
		priv->enable_beacon = false;
		priv->tx_multicast = false;
		priv->aid0_bit_set = false;
		priv->buffered_multicasts = false;
		priv->pspoll_mask = 0;
		reset.link_id = 0;
		wsm_reset(priv, &reset);
		break;
	case CW1200_JOIN_STATUS_MONITOR:
		cw1200_update_listening(priv, false);
		break;
	default:
		break;
	}
	priv->vif = NULL;
	priv->mode = NL80211_IFTYPE_MONITOR;
	eth_zero_addr(priv->mac_addr);
	memset(&priv->p2p_ps_modeinfo, 0, sizeof(priv->p2p_ps_modeinfo));
	cw1200_free_keys(priv);
	cw1200_setup_mac(priv);
	priv->listening = false;
	priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
	if (!__cw1200_flush(priv, true))
		wsm_unlock_tx(priv);

	mutex_unlock(&priv->conf_mutex);
}

int cw1200_change_interface(struct ieee80211_hw *dev,
			    struct ieee80211_vif *vif,
			    enum nl80211_iftype new_type,
			    bool p2p)
{
	int ret = 0;
	pr_debug("change_interface new: %d (%d), old: %d (%d)\n", new_type,
		 p2p, vif->type, vif->p2p);

	if (new_type != vif->type || vif->p2p != p2p) {
		cw1200_remove_interface(dev, vif);
		vif->type = new_type;
		vif->p2p = p2p;
		ret = cw1200_add_interface(dev, vif);
	}

	return ret;
}

int cw1200_config(struct ieee80211_hw *dev, int radio_idx, u32 changed)
{
	int ret = 0;
	struct cw1200_common *priv = dev->priv;
	struct ieee80211_conf *conf = &dev->conf;

	pr_debug("CONFIG CHANGED:  %08x\n", changed);

	down(&priv->scan.lock);
	mutex_lock(&priv->conf_mutex);
	/* TODO: IEEE80211_CONF_CHANGE_QOS */
	/* TODO: IEEE80211_CONF_CHANGE_LISTEN_INTERVAL */

	if (changed & IEEE80211_CONF_CHANGE_POWER) {
		priv->output_power = conf->power_level;
		pr_debug("[STA] TX power: %d\n", priv->output_power);
		wsm_set_output_power(priv, priv->output_power * 10);
	}

	if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) &&
	    (priv->channel != conf->chandef.chan)) {
		struct ieee80211_channel *ch = conf->chandef.chan;
		struct wsm_switch_channel channel = {
			.channel_number = ch->hw_value,
		};
		pr_debug("[STA] Freq %d (wsm ch: %d).\n",
			 ch->center_freq, ch->hw_value);

		/* __cw1200_flush() implicitly locks tx, if successful */
		if (!__cw1200_flush(priv, false)) {
			if (!wsm_switch_channel(priv, &channel)) {
				ret = wait_event_timeout(priv->channel_switch_done,
							 !priv->channel_switch_in_progress,
							 3 * HZ);
				if (ret) {

Annotation

Implementation Notes