drivers/net/wireless/ath/wil6210/cfg80211.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/ath/wil6210/cfg80211.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/ath/wil6210/cfg80211.c
Extension
.c
Size
89672 bytes
Lines
3314
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 (wil->vifs[i]) {
			wdev = vif_to_wdev(wil->vifs[i]);
			params.iftype_num[wdev->iftype]++;
		}
	}
	params.iftype_num[new_type]++;
	return cfg80211_check_combinations(wil->wiphy, &params);
}

static int wil_cfg80211_validate_change_iface(struct wil6210_priv *wil,
					      struct wil6210_vif *vif,
					      enum nl80211_iftype new_type)
{
	int i, ret = 0;
	struct wireless_dev *wdev;
	struct iface_combination_params params = {
		.num_different_channels = 1,
	};
	bool check_combos = false;

	for (i = 0; i < GET_MAX_VIFS(wil); i++) {
		struct wil6210_vif *vif_pos = wil->vifs[i];

		if (vif_pos && vif != vif_pos) {
			wdev = vif_to_wdev(vif_pos);
			params.iftype_num[wdev->iftype]++;
			check_combos = true;
		}
	}

	if (check_combos) {
		params.iftype_num[new_type]++;
		ret = cfg80211_check_combinations(wil->wiphy, &params);
	}
	return ret;
}

static struct wireless_dev *
wil_cfg80211_add_iface(struct wiphy *wiphy, const char *name,
		       unsigned char name_assign_type,
		       enum nl80211_iftype type,
		       struct vif_params *params)
{
	struct wil6210_priv *wil = wiphy_to_wil(wiphy);
	struct net_device *ndev_main = wil->main_ndev, *ndev;
	struct wil6210_vif *vif;
	struct wireless_dev *p2p_wdev, *wdev;
	int rc;

	wil_dbg_misc(wil, "add_iface, type %d\n", type);

	/* P2P device is not a real virtual interface, it is a management-only
	 * interface that shares the main interface.
	 * Skip concurrency checks here.
	 */
	if (type == NL80211_IFTYPE_P2P_DEVICE) {
		if (wil->p2p_wdev) {
			wil_err(wil, "P2P_DEVICE interface already created\n");
			return ERR_PTR(-EINVAL);
		}

		p2p_wdev = kzalloc_obj(*p2p_wdev);
		if (!p2p_wdev)
			return ERR_PTR(-ENOMEM);

		p2p_wdev->iftype = type;
		p2p_wdev->wiphy = wiphy;
		/* use our primary ethernet address */
		ether_addr_copy(p2p_wdev->address, ndev_main->perm_addr);

		wil->p2p_wdev = p2p_wdev;

		return p2p_wdev;
	}

	if (!wil->wiphy->n_iface_combinations) {
		wil_err(wil, "virtual interfaces not supported\n");
		return ERR_PTR(-EINVAL);
	}

	rc = wil_cfg80211_validate_add_iface(wil, type);
	if (rc) {
		wil_err(wil, "iface validation failed, err=%d\n", rc);
		return ERR_PTR(rc);
	}

	vif = wil_vif_alloc(wil, name, name_assign_type, type);
	if (IS_ERR(vif))
		return ERR_CAST(vif);

Annotation

Implementation Notes