drivers/net/wireless/zydas/zd1211rw/zd_chip.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/zydas/zd1211rw/zd_chip.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/zydas/zd1211rw/zd_chip.c
Extension
.c
Size
39519 bytes
Lines
1548
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

struct aw_pt_bi {
	u32 atim_wnd_period;
	u32 pre_tbtt;
	u32 beacon_interval;
};

static int get_aw_pt_bi(struct zd_chip *chip, struct aw_pt_bi *s)
{
	int r;
	static const zd_addr_t aw_pt_bi_addr[] =
		{ CR_ATIM_WND_PERIOD, CR_PRE_TBTT, CR_BCN_INTERVAL };
	u32 values[3];

	r = zd_ioread32v_locked(chip, values, (const zd_addr_t *)aw_pt_bi_addr,
		         ARRAY_SIZE(aw_pt_bi_addr));
	if (r) {
		memset(s, 0, sizeof(*s));
		return r;
	}

	s->atim_wnd_period = values[0];
	s->pre_tbtt = values[1];
	s->beacon_interval = values[2];
	return 0;
}

static int set_aw_pt_bi(struct zd_chip *chip, struct aw_pt_bi *s)
{
	struct zd_ioreq32 reqs[3];
	u16 b_interval = s->beacon_interval & 0xffff;

	if (b_interval <= 5)
		b_interval = 5;
	if (s->pre_tbtt < 4 || s->pre_tbtt >= b_interval)
		s->pre_tbtt = b_interval - 1;
	if (s->atim_wnd_period >= s->pre_tbtt)
		s->atim_wnd_period = s->pre_tbtt - 1;

	reqs[0].addr = CR_ATIM_WND_PERIOD;
	reqs[0].value = s->atim_wnd_period;
	reqs[1].addr = CR_PRE_TBTT;
	reqs[1].value = s->pre_tbtt;
	reqs[2].addr = CR_BCN_INTERVAL;
	reqs[2].value = (s->beacon_interval & ~0xffff) | b_interval;

	return zd_iowrite32a_locked(chip, reqs, ARRAY_SIZE(reqs));
}


static int set_beacon_interval(struct zd_chip *chip, u16 interval,
			       u8 dtim_period, int type)
{
	int r;
	struct aw_pt_bi s;
	u32 b_interval, mode_flag;

	ZD_ASSERT(mutex_is_locked(&chip->mutex));

	if (interval > 0) {
		switch (type) {
		case NL80211_IFTYPE_ADHOC:
		case NL80211_IFTYPE_MESH_POINT:
			mode_flag = BCN_MODE_IBSS;
			break;
		case NL80211_IFTYPE_AP:
			mode_flag = BCN_MODE_AP;
			break;
		default:
			mode_flag = 0;
			break;
		}
	} else {
		dtim_period = 0;
		mode_flag = 0;
	}

	b_interval = mode_flag | (dtim_period << 16) | interval;

	r = zd_iowrite32_locked(chip, b_interval, CR_BCN_INTERVAL);
	if (r)
		return r;
	r = get_aw_pt_bi(chip, &s);
	if (r)
		return r;
	return set_aw_pt_bi(chip, &s);
}

int zd_set_beacon_interval(struct zd_chip *chip, u16 interval, u8 dtim_period,
			   int type)
{

Annotation

Implementation Notes