Linux Audio

Check our new training course

Loading...
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Firmware I/O code for mac80211 Prism54 drivers
  4 *
  5 * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
  6 * Copyright (c) 2007-2009, Christian Lamparter <chunkeey@web.de>
  7 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
  8 *
  9 * Based on:
 10 * - the islsm (softmac prism54) driver, which is:
 11 *   Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
 12 * - stlc45xx driver
 13 *   Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
 14 */
 15
 16#include <linux/slab.h>
 17#include <linux/firmware.h>
 18#include <linux/etherdevice.h>
 19#include <linux/export.h>
 20
 21#include <net/mac80211.h>
 22
 23#include "p54.h"
 24#include "eeprom.h"
 25#include "lmac.h"
 26
 27int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
 28{
 29	struct p54_common *priv = dev->priv;
 30	struct exp_if *exp_if;
 31	struct bootrec *bootrec;
 32	u32 *data = (u32 *)fw->data;
 33	u32 *end_data = (u32 *)fw->data + (fw->size >> 2);
 34	u8 *fw_version = NULL;
 35	size_t len;
 36	int i;
 37	int maxlen;
 38
 39	if (priv->rx_start)
 40		return 0;
 41
 42	while (data < end_data && *data)
 43		data++;
 44
 45	while (data < end_data && !*data)
 46		data++;
 47
 48	bootrec = (struct bootrec *) data;
 49
 50	while (bootrec->data <= end_data && (bootrec->data +
 51	       (len = le32_to_cpu(bootrec->len))) <= end_data) {
 52		u32 code = le32_to_cpu(bootrec->code);
 53		switch (code) {
 54		case BR_CODE_COMPONENT_ID:
 55			priv->fw_interface = be32_to_cpup((__be32 *)
 56					     bootrec->data);
 57			switch (priv->fw_interface) {
 58			case FW_LM86:
 59			case FW_LM20:
 60			case FW_LM87: {
 61				char *iftype = (char *)bootrec->data;
 62				wiphy_info(priv->hw->wiphy,
 63					   "p54 detected a LM%c%c firmware\n",
 64					   iftype[2], iftype[3]);
 65				break;
 66				}
 67			case FW_FMAC:
 68			default:
 69				wiphy_err(priv->hw->wiphy,
 70					  "unsupported firmware\n");
 71				return -ENODEV;
 72			}
 73			break;
 74		case BR_CODE_COMPONENT_VERSION:
 75			/* 24 bytes should be enough for all firmwares */
 76			if (strnlen((unsigned char *) bootrec->data, 24) < 24)
 77				fw_version = (unsigned char *) bootrec->data;
 78			break;
 79		case BR_CODE_DESCR: {
 80			struct bootrec_desc *desc =
 81				(struct bootrec_desc *)bootrec->data;
 82			priv->rx_start = le32_to_cpu(desc->rx_start);
 83			/* FIXME add sanity checking */
 84			priv->rx_end = le32_to_cpu(desc->rx_end) - 0x3500;
 85			priv->headroom = desc->headroom;
 86			priv->tailroom = desc->tailroom;
 87			priv->privacy_caps = desc->privacy_caps;
 88			priv->rx_keycache_size = desc->rx_keycache_size;
 89			if (le32_to_cpu(bootrec->len) == 11)
 90				priv->rx_mtu = le16_to_cpu(desc->rx_mtu);
 91			else
 92				priv->rx_mtu = (size_t)
 93					0x620 - priv->tx_hdr_len;
 94			maxlen = priv->tx_hdr_len + /* USB devices */
 95				 sizeof(struct p54_rx_data) +
 96				 4 + /* rx alignment */
 97				 IEEE80211_MAX_FRAG_THRESHOLD;
 98			if (priv->rx_mtu > maxlen && PAGE_SIZE == 4096) {
 99				printk(KERN_INFO "p54: rx_mtu reduced from %d "
100				       "to %d\n", priv->rx_mtu, maxlen);
101				priv->rx_mtu = maxlen;
102			}
103			break;
104			}
105		case BR_CODE_EXPOSED_IF:
106			exp_if = (struct exp_if *) bootrec->data;
107			for (i = 0; i < (len * sizeof(*exp_if) / 4); i++)
108				if (exp_if[i].if_id == cpu_to_le16(IF_ID_LMAC))
109					priv->fw_var = le16_to_cpu(exp_if[i].variant);
110			break;
111		case BR_CODE_DEPENDENT_IF:
112			break;
113		case BR_CODE_END_OF_BRA:
114		case LEGACY_BR_CODE_END_OF_BRA:
115			end_data = NULL;
116			break;
117		default:
118			break;
119		}
120		bootrec = (struct bootrec *)&bootrec->data[len];
121	}
122
123	if (fw_version) {
124		wiphy_info(priv->hw->wiphy,
125			   "FW rev %s - Softmac protocol %x.%x\n",
126			   fw_version, priv->fw_var >> 8, priv->fw_var & 0xff);
127		snprintf(dev->wiphy->fw_version, sizeof(dev->wiphy->fw_version),
128				"%.19s - %x.%x", fw_version,
129				priv->fw_var >> 8, priv->fw_var & 0xff);
130	}
131
132	if (priv->fw_var < 0x500)
133		wiphy_info(priv->hw->wiphy,
134			   "you are using an obsolete firmware. "
135			   "visit http://wireless.wiki.kernel.org/en/users/Drivers/p54 "
136			   "and grab one for \"kernel >= 2.6.28\"!\n");
137
138	if (priv->fw_var >= 0x300) {
139		/* Firmware supports QoS, use it! */
140
141		if (priv->fw_var >= 0x500) {
142			priv->tx_stats[P54_QUEUE_AC_VO].limit = 16;
143			priv->tx_stats[P54_QUEUE_AC_VI].limit = 16;
144			priv->tx_stats[P54_QUEUE_AC_BE].limit = 16;
145			priv->tx_stats[P54_QUEUE_AC_BK].limit = 16;
146		} else {
147			priv->tx_stats[P54_QUEUE_AC_VO].limit = 3;
148			priv->tx_stats[P54_QUEUE_AC_VI].limit = 4;
149			priv->tx_stats[P54_QUEUE_AC_BE].limit = 3;
150			priv->tx_stats[P54_QUEUE_AC_BK].limit = 2;
151		}
152		priv->hw->queues = P54_QUEUE_AC_NUM;
153	}
154
155	wiphy_info(priv->hw->wiphy,
156		   "cryptographic accelerator WEP:%s, TKIP:%s, CCMP:%s\n",
157		   (priv->privacy_caps & BR_DESC_PRIV_CAP_WEP) ? "YES" : "no",
158		   (priv->privacy_caps &
159		    (BR_DESC_PRIV_CAP_TKIP | BR_DESC_PRIV_CAP_MICHAEL))
160		   ? "YES" : "no",
161		   (priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP)
162		   ? "YES" : "no");
163
164	if (priv->rx_keycache_size) {
165		/*
166		 * NOTE:
167		 *
168		 * The firmware provides at most 255 (0 - 254) slots
169		 * for keys which are then used to offload decryption.
170		 * As a result the 255 entry (aka 0xff) can be used
171		 * safely by the driver to mark keys that didn't fit
172		 * into the full cache. This trick saves us from
173		 * keeping a extra list for uploaded keys.
174		 */
175
176		priv->used_rxkeys = bitmap_zalloc(priv->rx_keycache_size,
177						  GFP_KERNEL);
178		if (!priv->used_rxkeys)
179			return -ENOMEM;
180	}
181
182	return 0;
183}
184EXPORT_SYMBOL_GPL(p54_parse_firmware);
185
186static struct sk_buff *p54_alloc_skb(struct p54_common *priv, u16 hdr_flags,
187				     u16 payload_len, u16 type, gfp_t memflags)
188{
189	struct p54_hdr *hdr;
190	struct sk_buff *skb;
191	size_t frame_len = sizeof(*hdr) + payload_len;
192
193	if (frame_len > P54_MAX_CTRL_FRAME_LEN)
194		return NULL;
195
196	if (unlikely(skb_queue_len(&priv->tx_pending) > 64))
197		return NULL;
198
199	skb = __dev_alloc_skb(priv->tx_hdr_len + frame_len, memflags);
200	if (!skb)
201		return NULL;
202	skb_reserve(skb, priv->tx_hdr_len);
203
204	hdr = skb_put(skb, sizeof(*hdr));
205	hdr->flags = cpu_to_le16(hdr_flags);
206	hdr->len = cpu_to_le16(payload_len);
207	hdr->type = cpu_to_le16(type);
208	hdr->tries = hdr->rts_tries = 0;
209	return skb;
210}
211
212int p54_download_eeprom(struct p54_common *priv, void *buf,
213			u16 offset, u16 len)
214{
215	struct p54_eeprom_lm86 *eeprom_hdr;
216	struct sk_buff *skb;
217	size_t eeprom_hdr_size;
218	int ret = 0;
219	long timeout;
220
221	if (priv->fw_var >= 0x509)
222		eeprom_hdr_size = sizeof(*eeprom_hdr);
223	else
224		eeprom_hdr_size = 0x4;
225
226	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL, eeprom_hdr_size +
227			    len, P54_CONTROL_TYPE_EEPROM_READBACK,
228			    GFP_KERNEL);
229	if (unlikely(!skb))
230		return -ENOMEM;
231
232	mutex_lock(&priv->eeprom_mutex);
233	priv->eeprom = buf;
234	eeprom_hdr = skb_put(skb, eeprom_hdr_size + len);
235
236	if (priv->fw_var < 0x509) {
237		eeprom_hdr->v1.offset = cpu_to_le16(offset);
238		eeprom_hdr->v1.len = cpu_to_le16(len);
239	} else {
240		eeprom_hdr->v2.offset = cpu_to_le32(offset);
241		eeprom_hdr->v2.len = cpu_to_le16(len);
242		eeprom_hdr->v2.magic2 = 0xf;
243		memcpy(eeprom_hdr->v2.magic, (const char *)"LOCK", 4);
244	}
245
246	p54_tx(priv, skb);
247
248	timeout = wait_for_completion_interruptible_timeout(
249			&priv->eeprom_comp, HZ);
250	if (timeout <= 0) {
251		wiphy_err(priv->hw->wiphy,
252			"device does not respond or signal received!\n");
253		ret = -EBUSY;
254	}
255	priv->eeprom = NULL;
256	mutex_unlock(&priv->eeprom_mutex);
257	return ret;
258}
259
260int p54_update_beacon_tim(struct p54_common *priv, u16 aid, bool set)
261{
262	struct sk_buff *skb;
263	struct p54_tim *tim;
264
265	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*tim),
266			    P54_CONTROL_TYPE_TIM, GFP_ATOMIC);
267	if (unlikely(!skb))
268		return -ENOMEM;
269
270	tim = skb_put(skb, sizeof(*tim));
271	tim->count = 1;
272	tim->entry[0] = cpu_to_le16(set ? (aid | 0x8000) : aid);
273	p54_tx(priv, skb);
274	return 0;
275}
276
277int p54_sta_unlock(struct p54_common *priv, u8 *addr)
278{
279	struct sk_buff *skb;
280	struct p54_sta_unlock *sta;
281
282	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*sta),
283			    P54_CONTROL_TYPE_PSM_STA_UNLOCK, GFP_ATOMIC);
284	if (unlikely(!skb))
285		return -ENOMEM;
286
287	sta = skb_put(skb, sizeof(*sta));
288	memcpy(sta->addr, addr, ETH_ALEN);
289	p54_tx(priv, skb);
290	return 0;
291}
292
293int p54_tx_cancel(struct p54_common *priv, __le32 req_id)
294{
295	struct sk_buff *skb;
296	struct p54_txcancel *cancel;
297	u32 _req_id = le32_to_cpu(req_id);
298
299	if (unlikely(_req_id < priv->rx_start || _req_id > priv->rx_end))
300		return -EINVAL;
301
302	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*cancel),
303			    P54_CONTROL_TYPE_TXCANCEL, GFP_ATOMIC);
304	if (unlikely(!skb))
305		return -ENOMEM;
306
307	cancel = skb_put(skb, sizeof(*cancel));
308	cancel->req_id = req_id;
309	p54_tx(priv, skb);
310	return 0;
311}
312
313int p54_setup_mac(struct p54_common *priv)
314{
315	struct sk_buff *skb;
316	struct p54_setup_mac *setup;
317	u16 mode;
318
319	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*setup),
320			    P54_CONTROL_TYPE_SETUP, GFP_ATOMIC);
321	if (!skb)
322		return -ENOMEM;
323
324	setup = skb_put(skb, sizeof(*setup));
325	if (!(priv->hw->conf.flags & IEEE80211_CONF_IDLE)) {
326		switch (priv->mode) {
327		case NL80211_IFTYPE_STATION:
328			mode = P54_FILTER_TYPE_STATION;
329			break;
330		case NL80211_IFTYPE_AP:
331			mode = P54_FILTER_TYPE_AP;
332			break;
333		case NL80211_IFTYPE_ADHOC:
334		case NL80211_IFTYPE_MESH_POINT:
335			mode = P54_FILTER_TYPE_IBSS;
336			break;
337		case NL80211_IFTYPE_MONITOR:
338			mode = P54_FILTER_TYPE_PROMISCUOUS;
339			break;
340		default:
341			mode = P54_FILTER_TYPE_HIBERNATE;
342			break;
343		}
344
345		/*
346		 * "TRANSPARENT and PROMISCUOUS are mutually exclusive"
347		 * STSW45X0C LMAC API - page 12
348		 */
349		if (priv->filter_flags & FIF_OTHER_BSS &&
350		    (mode != P54_FILTER_TYPE_PROMISCUOUS))
351			mode |= P54_FILTER_TYPE_TRANSPARENT;
352	} else {
353		mode = P54_FILTER_TYPE_HIBERNATE;
354	}
355
356	setup->mac_mode = cpu_to_le16(mode);
357	memcpy(setup->mac_addr, priv->mac_addr, ETH_ALEN);
358	memcpy(setup->bssid, priv->bssid, ETH_ALEN);
359	setup->rx_antenna = 2 & priv->rx_diversity_mask; /* automatic */
360	setup->rx_align = 0;
361	if (priv->fw_var < 0x500) {
362		setup->v1.basic_rate_mask = cpu_to_le32(priv->basic_rate_mask);
363		memset(setup->v1.rts_rates, 0, 8);
364		setup->v1.rx_addr = cpu_to_le32(priv->rx_end);
365		setup->v1.max_rx = cpu_to_le16(priv->rx_mtu);
366		setup->v1.rxhw = cpu_to_le16(priv->rxhw);
367		setup->v1.wakeup_timer = cpu_to_le16(priv->wakeup_timer);
368		setup->v1.unalloc0 = cpu_to_le16(0);
369	} else {
370		setup->v2.rx_addr = cpu_to_le32(priv->rx_end);
371		setup->v2.max_rx = cpu_to_le16(priv->rx_mtu);
372		setup->v2.rxhw = cpu_to_le16(priv->rxhw);
373		setup->v2.timer = cpu_to_le16(priv->wakeup_timer);
374		setup->v2.truncate = cpu_to_le16(48896);
375		setup->v2.basic_rate_mask = cpu_to_le32(priv->basic_rate_mask);
376		setup->v2.sbss_offset = 0;
377		setup->v2.mcast_window = 0;
378		setup->v2.rx_rssi_threshold = 0;
379		setup->v2.rx_ed_threshold = 0;
380		setup->v2.ref_clock = cpu_to_le32(644245094);
381		setup->v2.lpf_bandwidth = cpu_to_le16(65535);
382		setup->v2.osc_start_delay = cpu_to_le16(65535);
383	}
384	p54_tx(priv, skb);
385	priv->phy_idle = mode == P54_FILTER_TYPE_HIBERNATE;
386	return 0;
387}
388
389int p54_scan(struct p54_common *priv, u16 mode, u16 dwell)
390{
391	struct sk_buff *skb;
392	struct p54_hdr *hdr;
393	struct p54_scan_head *head;
394	struct p54_iq_autocal_entry *iq_autocal;
395	union p54_scan_body_union *body;
396	struct p54_scan_tail_rate *rate;
397	struct pda_rssi_cal_entry *rssi;
398	struct p54_rssi_db_entry *rssi_data;
399	unsigned int i;
400	void *entry;
401	__le16 freq = cpu_to_le16(priv->hw->conf.chandef.chan->center_freq);
402
403	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*head) +
404			    2 + sizeof(*iq_autocal) + sizeof(*body) +
405			    sizeof(*rate) + 2 * sizeof(*rssi),
406			    P54_CONTROL_TYPE_SCAN, GFP_ATOMIC);
407	if (!skb)
408		return -ENOMEM;
409
410	head = skb_put(skb, sizeof(*head));
411	memset(head->scan_params, 0, sizeof(head->scan_params));
412	head->mode = cpu_to_le16(mode);
413	head->dwell = cpu_to_le16(dwell);
414	head->freq = freq;
415
416	if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
417		__le16 *pa_power_points = skb_put(skb, 2);
418		*pa_power_points = cpu_to_le16(0x0c);
419	}
420
421	iq_autocal = skb_put(skb, sizeof(*iq_autocal));
422	for (i = 0; i < priv->iq_autocal_len; i++) {
423		if (priv->iq_autocal[i].freq != freq)
424			continue;
425
426		memcpy(iq_autocal, &priv->iq_autocal[i].params,
427		       sizeof(struct p54_iq_autocal_entry));
428		break;
429	}
430	if (i == priv->iq_autocal_len)
431		goto err;
432
433	if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW)
434		body = skb_put(skb, sizeof(body->longbow));
435	else
436		body = skb_put(skb, sizeof(body->normal));
437
438	for (i = 0; i < priv->output_limit->entries; i++) {
439		__le16 *entry_freq = (void *) (priv->output_limit->data +
440				     priv->output_limit->entry_size * i);
441
442		if (*entry_freq != freq)
443			continue;
444
445		if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
446			memcpy(&body->longbow.power_limits,
447			       (void *) entry_freq + sizeof(__le16),
448			       priv->output_limit->entry_size);
449		} else {
450			struct pda_channel_output_limit *limits =
451			       (void *) entry_freq;
452
453			body->normal.val_barker = 0x38;
454			body->normal.val_bpsk = body->normal.dup_bpsk =
455				limits->val_bpsk;
456			body->normal.val_qpsk = body->normal.dup_qpsk =
457				limits->val_qpsk;
458			body->normal.val_16qam = body->normal.dup_16qam =
459				limits->val_16qam;
460			body->normal.val_64qam = body->normal.dup_64qam =
461				limits->val_64qam;
462		}
463		break;
464	}
465	if (i == priv->output_limit->entries)
466		goto err;
467
468	entry = (void *)(priv->curve_data->data + priv->curve_data->offset);
469	for (i = 0; i < priv->curve_data->entries; i++) {
470		if (*((__le16 *)entry) != freq) {
471			entry += priv->curve_data->entry_size;
472			continue;
473		}
474
475		if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
476			memcpy(&body->longbow.curve_data,
477				entry + sizeof(__le16),
478				priv->curve_data->entry_size);
479		} else {
480			struct p54_scan_body *chan = &body->normal;
481			struct pda_pa_curve_data *curve_data =
482				(void *) priv->curve_data->data;
483
484			entry += sizeof(__le16);
485			chan->pa_points_per_curve = 8;
486			memset(chan->curve_data, 0, sizeof(chan->curve_data));
487			memcpy(chan->curve_data, entry,
488			       sizeof(struct p54_pa_curve_data_sample) *
489			       min((u8)8, curve_data->points_per_channel));
490		}
491		break;
492	}
493	if (i == priv->curve_data->entries)
494		goto err;
495
496	if ((priv->fw_var >= 0x500) && (priv->fw_var < 0x509)) {
497		rate = skb_put(skb, sizeof(*rate));
498		rate->basic_rate_mask = cpu_to_le32(priv->basic_rate_mask);
499		for (i = 0; i < sizeof(rate->rts_rates); i++)
500			rate->rts_rates[i] = i;
501	}
502
503	rssi = skb_put(skb, sizeof(*rssi));
504	rssi_data = p54_rssi_find(priv, le16_to_cpu(freq));
505	rssi->mul = cpu_to_le16(rssi_data->mul);
506	rssi->add = cpu_to_le16(rssi_data->add);
507	if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
508		/* Longbow frontend needs ever more */
509		rssi = skb_put(skb, sizeof(*rssi));
510		rssi->mul = cpu_to_le16(rssi_data->longbow_unkn);
511		rssi->add = cpu_to_le16(rssi_data->longbow_unk2);
512	}
513
514	if (priv->fw_var >= 0x509) {
515		rate = skb_put(skb, sizeof(*rate));
516		rate->basic_rate_mask = cpu_to_le32(priv->basic_rate_mask);
517		for (i = 0; i < sizeof(rate->rts_rates); i++)
518			rate->rts_rates[i] = i;
519	}
520
521	hdr = (struct p54_hdr *) skb->data;
522	hdr->len = cpu_to_le16(skb->len - sizeof(*hdr));
523
524	p54_tx(priv, skb);
525	priv->cur_rssi = rssi_data;
526	return 0;
527
528err:
529	wiphy_err(priv->hw->wiphy, "frequency change to channel %d failed.\n",
530		  ieee80211_frequency_to_channel(
531			  priv->hw->conf.chandef.chan->center_freq));
532
533	dev_kfree_skb_any(skb);
534	return -EINVAL;
535}
536
537int p54_set_leds(struct p54_common *priv)
538{
539	struct sk_buff *skb;
540	struct p54_led *led;
541
542	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*led),
543			    P54_CONTROL_TYPE_LED, GFP_ATOMIC);
544	if (unlikely(!skb))
545		return -ENOMEM;
546
547	led = skb_put(skb, sizeof(*led));
548	led->flags = cpu_to_le16(0x0003);
549	led->mask[0] = led->mask[1] = cpu_to_le16(priv->softled_state);
550	led->delay[0] = cpu_to_le16(1);
551	led->delay[1] = cpu_to_le16(0);
552	p54_tx(priv, skb);
553	return 0;
554}
555
556int p54_set_edcf(struct p54_common *priv)
557{
558	struct sk_buff *skb;
559	struct p54_edcf *edcf;
560	u8 rtd;
561
562	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*edcf),
563			    P54_CONTROL_TYPE_DCFINIT, GFP_ATOMIC);
564	if (unlikely(!skb))
565		return -ENOMEM;
566
567	edcf = skb_put(skb, sizeof(*edcf));
568	if (priv->use_short_slot) {
569		edcf->slottime = 9;
570		edcf->sifs = 0x10;
571		edcf->eofpad = 0x00;
572	} else {
573		edcf->slottime = 20;
574		edcf->sifs = 0x0a;
575		edcf->eofpad = 0x06;
576	}
577	/*
578	 * calculate the extra round trip delay according to the
579	 * formula from 802.11-2007 17.3.8.6.
580	 */
581	rtd = 3 * priv->coverage_class;
582	edcf->slottime += rtd;
583	edcf->round_trip_delay = cpu_to_le16(rtd);
584	/* (see prism54/isl_oid.h for further details) */
585	edcf->frameburst = cpu_to_le16(0);
586	edcf->flags = 0;
587	memset(edcf->mapping, 0, sizeof(edcf->mapping));
588	memcpy(edcf->queue, priv->qos_params, sizeof(edcf->queue));
589	p54_tx(priv, skb);
590	return 0;
591}
592
593int p54_set_ps(struct p54_common *priv)
594{
595	struct sk_buff *skb;
596	struct p54_psm *psm;
597	unsigned int i;
598	u16 mode;
599
600	if (priv->hw->conf.flags & IEEE80211_CONF_PS &&
601	    !priv->powersave_override)
602		mode = P54_PSM | P54_PSM_BEACON_TIMEOUT | P54_PSM_DTIM |
603		       P54_PSM_CHECKSUM | P54_PSM_MCBC;
604	else
605		mode = P54_PSM_CAM;
606
607	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*psm),
608			    P54_CONTROL_TYPE_PSM, GFP_ATOMIC);
609	if (!skb)
610		return -ENOMEM;
611
612	psm = skb_put(skb, sizeof(*psm));
613	psm->mode = cpu_to_le16(mode);
614	psm->aid = cpu_to_le16(priv->aid);
615	for (i = 0; i < ARRAY_SIZE(psm->intervals); i++) {
616		psm->intervals[i].interval =
617			cpu_to_le16(priv->hw->conf.listen_interval);
618		psm->intervals[i].periods = cpu_to_le16(1);
619	}
620
621	psm->beacon_rssi_skip_max = 200;
622	psm->rssi_delta_threshold = 0;
623	psm->nr = 1;
624	psm->exclude[0] = WLAN_EID_TIM;
625
626	p54_tx(priv, skb);
627	priv->phy_ps = mode != P54_PSM_CAM;
628	return 0;
629}
630
631int p54_init_xbow_synth(struct p54_common *priv)
632{
633	struct sk_buff *skb;
634	struct p54_xbow_synth *xbow;
635
636	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*xbow),
637			    P54_CONTROL_TYPE_XBOW_SYNTH_CFG, GFP_KERNEL);
638	if (unlikely(!skb))
639		return -ENOMEM;
640
641	xbow = skb_put(skb, sizeof(*xbow));
642	xbow->magic1 = cpu_to_le16(0x1);
643	xbow->magic2 = cpu_to_le16(0x2);
644	xbow->freq = cpu_to_le16(5390);
645	memset(xbow->padding, 0, sizeof(xbow->padding));
646	p54_tx(priv, skb);
647	return 0;
648}
649
650int p54_upload_key(struct p54_common *priv, u8 algo, int slot, u8 idx, u8 len,
651		   u8 *addr, u8* key)
652{
653	struct sk_buff *skb;
654	struct p54_keycache *rxkey;
655
656	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*rxkey),
657			    P54_CONTROL_TYPE_RX_KEYCACHE, GFP_KERNEL);
658	if (unlikely(!skb))
659		return -ENOMEM;
660
661	rxkey = skb_put(skb, sizeof(*rxkey));
662	rxkey->entry = slot;
663	rxkey->key_id = idx;
664	rxkey->key_type = algo;
665	if (addr)
666		memcpy(rxkey->mac, addr, ETH_ALEN);
667	else
668		eth_broadcast_addr(rxkey->mac);
669
670	switch (algo) {
671	case P54_CRYPTO_WEP:
672	case P54_CRYPTO_AESCCMP:
673		rxkey->key_len = min_t(u8, 16, len);
674		memcpy(rxkey->key, key, rxkey->key_len);
675		break;
676
677	case P54_CRYPTO_TKIPMICHAEL:
678		rxkey->key_len = 24;
679		memcpy(rxkey->key, key, 16);
680		memcpy(&(rxkey->key[16]), &(key
681			[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY]), 8);
682		break;
683
684	case P54_CRYPTO_NONE:
685		rxkey->key_len = 0;
686		memset(rxkey->key, 0, sizeof(rxkey->key));
687		break;
688
689	default:
690		wiphy_err(priv->hw->wiphy,
691			  "invalid cryptographic algorithm: %d\n", algo);
692		dev_kfree_skb(skb);
693		return -EINVAL;
694	}
695
696	p54_tx(priv, skb);
697	return 0;
698}
699
700int p54_fetch_statistics(struct p54_common *priv)
701{
702	struct ieee80211_tx_info *txinfo;
703	struct p54_tx_info *p54info;
704	struct sk_buff *skb;
705
706	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL,
707			    sizeof(struct p54_statistics),
708			    P54_CONTROL_TYPE_STAT_READBACK, GFP_KERNEL);
709	if (!skb)
710		return -ENOMEM;
711
712	/*
713	 * The statistic feedback causes some extra headaches here, if it
714	 * is not to crash/corrupt the firmware data structures.
715	 *
716	 * Unlike all other Control Get OIDs we can not use helpers like
717	 * skb_put to reserve the space for the data we're requesting.
718	 * Instead the extra frame length -which will hold the results later-
719	 * will only be told to the p54_assign_address, so that following
720	 * frames won't be placed into the  allegedly empty area.
721	 */
722	txinfo = IEEE80211_SKB_CB(skb);
723	p54info = (void *) txinfo->rate_driver_data;
724	p54info->extra_len = sizeof(struct p54_statistics);
725
726	p54_tx(priv, skb);
727	return 0;
728}
729
730int p54_set_groupfilter(struct p54_common *priv)
731{
732	struct p54_group_address_table *grp;
733	struct sk_buff *skb;
734	bool on = false;
735
736	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*grp),
737			    P54_CONTROL_TYPE_GROUP_ADDRESS_TABLE, GFP_KERNEL);
738	if (!skb)
739		return -ENOMEM;
740
741	grp = skb_put(skb, sizeof(*grp));
742
743	on = !(priv->filter_flags & FIF_ALLMULTI) &&
744	     (priv->mc_maclist_num > 0 &&
745	      priv->mc_maclist_num <= MC_FILTER_ADDRESS_NUM);
746
747	if (on) {
748		grp->filter_enable = cpu_to_le16(1);
749		grp->num_address = cpu_to_le16(priv->mc_maclist_num);
750		memcpy(grp->mac_list, priv->mc_maclist, sizeof(grp->mac_list));
751	} else {
752		grp->filter_enable = cpu_to_le16(0);
753		grp->num_address = cpu_to_le16(0);
754		memset(grp->mac_list, 0, sizeof(grp->mac_list));
755	}
756
757	p54_tx(priv, skb);
758	return 0;
759}
  1/*
  2 * Firmware I/O code for mac80211 Prism54 drivers
  3 *
  4 * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
  5 * Copyright (c) 2007-2009, Christian Lamparter <chunkeey@web.de>
  6 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
  7 *
  8 * Based on:
  9 * - the islsm (softmac prism54) driver, which is:
 10 *   Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
 11 * - stlc45xx driver
 12 *   Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
 13 *
 14 * This program is free software; you can redistribute it and/or modify
 15 * it under the terms of the GNU General Public License version 2 as
 16 * published by the Free Software Foundation.
 17 */
 18
 19#include <linux/slab.h>
 20#include <linux/firmware.h>
 21#include <linux/etherdevice.h>
 22#include <linux/export.h>
 23
 24#include <net/mac80211.h>
 25
 26#include "p54.h"
 27#include "eeprom.h"
 28#include "lmac.h"
 29
 30int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
 31{
 32	struct p54_common *priv = dev->priv;
 33	struct exp_if *exp_if;
 34	struct bootrec *bootrec;
 35	u32 *data = (u32 *)fw->data;
 36	u32 *end_data = (u32 *)fw->data + (fw->size >> 2);
 37	u8 *fw_version = NULL;
 38	size_t len;
 39	int i;
 40	int maxlen;
 41
 42	if (priv->rx_start)
 43		return 0;
 44
 45	while (data < end_data && *data)
 46		data++;
 47
 48	while (data < end_data && !*data)
 49		data++;
 50
 51	bootrec = (struct bootrec *) data;
 52
 53	while (bootrec->data <= end_data && (bootrec->data +
 54	       (len = le32_to_cpu(bootrec->len))) <= end_data) {
 55		u32 code = le32_to_cpu(bootrec->code);
 56		switch (code) {
 57		case BR_CODE_COMPONENT_ID:
 58			priv->fw_interface = be32_to_cpup((__be32 *)
 59					     bootrec->data);
 60			switch (priv->fw_interface) {
 61			case FW_LM86:
 62			case FW_LM20:
 63			case FW_LM87: {
 64				char *iftype = (char *)bootrec->data;
 65				wiphy_info(priv->hw->wiphy,
 66					   "p54 detected a LM%c%c firmware\n",
 67					   iftype[2], iftype[3]);
 68				break;
 69				}
 70			case FW_FMAC:
 71			default:
 72				wiphy_err(priv->hw->wiphy,
 73					  "unsupported firmware\n");
 74				return -ENODEV;
 75			}
 76			break;
 77		case BR_CODE_COMPONENT_VERSION:
 78			/* 24 bytes should be enough for all firmwares */
 79			if (strnlen((unsigned char *) bootrec->data, 24) < 24)
 80				fw_version = (unsigned char *) bootrec->data;
 81			break;
 82		case BR_CODE_DESCR: {
 83			struct bootrec_desc *desc =
 84				(struct bootrec_desc *)bootrec->data;
 85			priv->rx_start = le32_to_cpu(desc->rx_start);
 86			/* FIXME add sanity checking */
 87			priv->rx_end = le32_to_cpu(desc->rx_end) - 0x3500;
 88			priv->headroom = desc->headroom;
 89			priv->tailroom = desc->tailroom;
 90			priv->privacy_caps = desc->privacy_caps;
 91			priv->rx_keycache_size = desc->rx_keycache_size;
 92			if (le32_to_cpu(bootrec->len) == 11)
 93				priv->rx_mtu = le16_to_cpu(desc->rx_mtu);
 94			else
 95				priv->rx_mtu = (size_t)
 96					0x620 - priv->tx_hdr_len;
 97			maxlen = priv->tx_hdr_len + /* USB devices */
 98				 sizeof(struct p54_rx_data) +
 99				 4 + /* rx alignment */
100				 IEEE80211_MAX_FRAG_THRESHOLD;
101			if (priv->rx_mtu > maxlen && PAGE_SIZE == 4096) {
102				printk(KERN_INFO "p54: rx_mtu reduced from %d "
103				       "to %d\n", priv->rx_mtu, maxlen);
104				priv->rx_mtu = maxlen;
105			}
106			break;
107			}
108		case BR_CODE_EXPOSED_IF:
109			exp_if = (struct exp_if *) bootrec->data;
110			for (i = 0; i < (len * sizeof(*exp_if) / 4); i++)
111				if (exp_if[i].if_id == cpu_to_le16(IF_ID_LMAC))
112					priv->fw_var = le16_to_cpu(exp_if[i].variant);
113			break;
114		case BR_CODE_DEPENDENT_IF:
115			break;
116		case BR_CODE_END_OF_BRA:
117		case LEGACY_BR_CODE_END_OF_BRA:
118			end_data = NULL;
119			break;
120		default:
121			break;
122		}
123		bootrec = (struct bootrec *)&bootrec->data[len];
124	}
125
126	if (fw_version) {
127		wiphy_info(priv->hw->wiphy,
128			   "FW rev %s - Softmac protocol %x.%x\n",
129			   fw_version, priv->fw_var >> 8, priv->fw_var & 0xff);
130		snprintf(dev->wiphy->fw_version, sizeof(dev->wiphy->fw_version),
131				"%s - %x.%x", fw_version,
132				priv->fw_var >> 8, priv->fw_var & 0xff);
133	}
134
135	if (priv->fw_var < 0x500)
136		wiphy_info(priv->hw->wiphy,
137			   "you are using an obsolete firmware. "
138			   "visit http://wireless.kernel.org/en/users/Drivers/p54 "
139			   "and grab one for \"kernel >= 2.6.28\"!\n");
140
141	if (priv->fw_var >= 0x300) {
142		/* Firmware supports QoS, use it! */
143
144		if (priv->fw_var >= 0x500) {
145			priv->tx_stats[P54_QUEUE_AC_VO].limit = 16;
146			priv->tx_stats[P54_QUEUE_AC_VI].limit = 16;
147			priv->tx_stats[P54_QUEUE_AC_BE].limit = 16;
148			priv->tx_stats[P54_QUEUE_AC_BK].limit = 16;
149		} else {
150			priv->tx_stats[P54_QUEUE_AC_VO].limit = 3;
151			priv->tx_stats[P54_QUEUE_AC_VI].limit = 4;
152			priv->tx_stats[P54_QUEUE_AC_BE].limit = 3;
153			priv->tx_stats[P54_QUEUE_AC_BK].limit = 2;
154		}
155		priv->hw->queues = P54_QUEUE_AC_NUM;
156	}
157
158	wiphy_info(priv->hw->wiphy,
159		   "cryptographic accelerator WEP:%s, TKIP:%s, CCMP:%s\n",
160		   (priv->privacy_caps & BR_DESC_PRIV_CAP_WEP) ? "YES" : "no",
161		   (priv->privacy_caps &
162		    (BR_DESC_PRIV_CAP_TKIP | BR_DESC_PRIV_CAP_MICHAEL))
163		   ? "YES" : "no",
164		   (priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP)
165		   ? "YES" : "no");
166
167	if (priv->rx_keycache_size) {
168		/*
169		 * NOTE:
170		 *
171		 * The firmware provides at most 255 (0 - 254) slots
172		 * for keys which are then used to offload decryption.
173		 * As a result the 255 entry (aka 0xff) can be used
174		 * safely by the driver to mark keys that didn't fit
175		 * into the full cache. This trick saves us from
176		 * keeping a extra list for uploaded keys.
177		 */
178
179		priv->used_rxkeys = kcalloc(BITS_TO_LONGS(priv->rx_keycache_size),
180					    sizeof(long),
181					    GFP_KERNEL);
182
183		if (!priv->used_rxkeys)
184			return -ENOMEM;
185	}
186
187	return 0;
188}
189EXPORT_SYMBOL_GPL(p54_parse_firmware);
190
191static struct sk_buff *p54_alloc_skb(struct p54_common *priv, u16 hdr_flags,
192				     u16 payload_len, u16 type, gfp_t memflags)
193{
194	struct p54_hdr *hdr;
195	struct sk_buff *skb;
196	size_t frame_len = sizeof(*hdr) + payload_len;
197
198	if (frame_len > P54_MAX_CTRL_FRAME_LEN)
199		return NULL;
200
201	if (unlikely(skb_queue_len(&priv->tx_pending) > 64))
202		return NULL;
203
204	skb = __dev_alloc_skb(priv->tx_hdr_len + frame_len, memflags);
205	if (!skb)
206		return NULL;
207	skb_reserve(skb, priv->tx_hdr_len);
208
209	hdr = skb_put(skb, sizeof(*hdr));
210	hdr->flags = cpu_to_le16(hdr_flags);
211	hdr->len = cpu_to_le16(payload_len);
212	hdr->type = cpu_to_le16(type);
213	hdr->tries = hdr->rts_tries = 0;
214	return skb;
215}
216
217int p54_download_eeprom(struct p54_common *priv, void *buf,
218			u16 offset, u16 len)
219{
220	struct p54_eeprom_lm86 *eeprom_hdr;
221	struct sk_buff *skb;
222	size_t eeprom_hdr_size;
223	int ret = 0;
224	long timeout;
225
226	if (priv->fw_var >= 0x509)
227		eeprom_hdr_size = sizeof(*eeprom_hdr);
228	else
229		eeprom_hdr_size = 0x4;
230
231	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL, eeprom_hdr_size +
232			    len, P54_CONTROL_TYPE_EEPROM_READBACK,
233			    GFP_KERNEL);
234	if (unlikely(!skb))
235		return -ENOMEM;
236
237	mutex_lock(&priv->eeprom_mutex);
238	priv->eeprom = buf;
239	eeprom_hdr = skb_put(skb, eeprom_hdr_size + len);
240
241	if (priv->fw_var < 0x509) {
242		eeprom_hdr->v1.offset = cpu_to_le16(offset);
243		eeprom_hdr->v1.len = cpu_to_le16(len);
244	} else {
245		eeprom_hdr->v2.offset = cpu_to_le32(offset);
246		eeprom_hdr->v2.len = cpu_to_le16(len);
247		eeprom_hdr->v2.magic2 = 0xf;
248		memcpy(eeprom_hdr->v2.magic, (const char *)"LOCK", 4);
249	}
250
251	p54_tx(priv, skb);
252
253	timeout = wait_for_completion_interruptible_timeout(
254			&priv->eeprom_comp, HZ);
255	if (timeout <= 0) {
256		wiphy_err(priv->hw->wiphy,
257			"device does not respond or signal received!\n");
258		ret = -EBUSY;
259	}
260	priv->eeprom = NULL;
261	mutex_unlock(&priv->eeprom_mutex);
262	return ret;
263}
264
265int p54_update_beacon_tim(struct p54_common *priv, u16 aid, bool set)
266{
267	struct sk_buff *skb;
268	struct p54_tim *tim;
269
270	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*tim),
271			    P54_CONTROL_TYPE_TIM, GFP_ATOMIC);
272	if (unlikely(!skb))
273		return -ENOMEM;
274
275	tim = skb_put(skb, sizeof(*tim));
276	tim->count = 1;
277	tim->entry[0] = cpu_to_le16(set ? (aid | 0x8000) : aid);
278	p54_tx(priv, skb);
279	return 0;
280}
281
282int p54_sta_unlock(struct p54_common *priv, u8 *addr)
283{
284	struct sk_buff *skb;
285	struct p54_sta_unlock *sta;
286
287	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*sta),
288			    P54_CONTROL_TYPE_PSM_STA_UNLOCK, GFP_ATOMIC);
289	if (unlikely(!skb))
290		return -ENOMEM;
291
292	sta = skb_put(skb, sizeof(*sta));
293	memcpy(sta->addr, addr, ETH_ALEN);
294	p54_tx(priv, skb);
295	return 0;
296}
297
298int p54_tx_cancel(struct p54_common *priv, __le32 req_id)
299{
300	struct sk_buff *skb;
301	struct p54_txcancel *cancel;
302	u32 _req_id = le32_to_cpu(req_id);
303
304	if (unlikely(_req_id < priv->rx_start || _req_id > priv->rx_end))
305		return -EINVAL;
306
307	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*cancel),
308			    P54_CONTROL_TYPE_TXCANCEL, GFP_ATOMIC);
309	if (unlikely(!skb))
310		return -ENOMEM;
311
312	cancel = skb_put(skb, sizeof(*cancel));
313	cancel->req_id = req_id;
314	p54_tx(priv, skb);
315	return 0;
316}
317
318int p54_setup_mac(struct p54_common *priv)
319{
320	struct sk_buff *skb;
321	struct p54_setup_mac *setup;
322	u16 mode;
323
324	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*setup),
325			    P54_CONTROL_TYPE_SETUP, GFP_ATOMIC);
326	if (!skb)
327		return -ENOMEM;
328
329	setup = skb_put(skb, sizeof(*setup));
330	if (!(priv->hw->conf.flags & IEEE80211_CONF_IDLE)) {
331		switch (priv->mode) {
332		case NL80211_IFTYPE_STATION:
333			mode = P54_FILTER_TYPE_STATION;
334			break;
335		case NL80211_IFTYPE_AP:
336			mode = P54_FILTER_TYPE_AP;
337			break;
338		case NL80211_IFTYPE_ADHOC:
339		case NL80211_IFTYPE_MESH_POINT:
340			mode = P54_FILTER_TYPE_IBSS;
341			break;
342		case NL80211_IFTYPE_MONITOR:
343			mode = P54_FILTER_TYPE_PROMISCUOUS;
344			break;
345		default:
346			mode = P54_FILTER_TYPE_HIBERNATE;
347			break;
348		}
349
350		/*
351		 * "TRANSPARENT and PROMISCUOUS are mutually exclusive"
352		 * STSW45X0C LMAC API - page 12
353		 */
354		if (priv->filter_flags & FIF_OTHER_BSS &&
355		    (mode != P54_FILTER_TYPE_PROMISCUOUS))
356			mode |= P54_FILTER_TYPE_TRANSPARENT;
357	} else {
358		mode = P54_FILTER_TYPE_HIBERNATE;
359	}
360
361	setup->mac_mode = cpu_to_le16(mode);
362	memcpy(setup->mac_addr, priv->mac_addr, ETH_ALEN);
363	memcpy(setup->bssid, priv->bssid, ETH_ALEN);
364	setup->rx_antenna = 2 & priv->rx_diversity_mask; /* automatic */
365	setup->rx_align = 0;
366	if (priv->fw_var < 0x500) {
367		setup->v1.basic_rate_mask = cpu_to_le32(priv->basic_rate_mask);
368		memset(setup->v1.rts_rates, 0, 8);
369		setup->v1.rx_addr = cpu_to_le32(priv->rx_end);
370		setup->v1.max_rx = cpu_to_le16(priv->rx_mtu);
371		setup->v1.rxhw = cpu_to_le16(priv->rxhw);
372		setup->v1.wakeup_timer = cpu_to_le16(priv->wakeup_timer);
373		setup->v1.unalloc0 = cpu_to_le16(0);
374	} else {
375		setup->v2.rx_addr = cpu_to_le32(priv->rx_end);
376		setup->v2.max_rx = cpu_to_le16(priv->rx_mtu);
377		setup->v2.rxhw = cpu_to_le16(priv->rxhw);
378		setup->v2.timer = cpu_to_le16(priv->wakeup_timer);
379		setup->v2.truncate = cpu_to_le16(48896);
380		setup->v2.basic_rate_mask = cpu_to_le32(priv->basic_rate_mask);
381		setup->v2.sbss_offset = 0;
382		setup->v2.mcast_window = 0;
383		setup->v2.rx_rssi_threshold = 0;
384		setup->v2.rx_ed_threshold = 0;
385		setup->v2.ref_clock = cpu_to_le32(644245094);
386		setup->v2.lpf_bandwidth = cpu_to_le16(65535);
387		setup->v2.osc_start_delay = cpu_to_le16(65535);
388	}
389	p54_tx(priv, skb);
390	priv->phy_idle = mode == P54_FILTER_TYPE_HIBERNATE;
391	return 0;
392}
393
394int p54_scan(struct p54_common *priv, u16 mode, u16 dwell)
395{
396	struct sk_buff *skb;
397	struct p54_hdr *hdr;
398	struct p54_scan_head *head;
399	struct p54_iq_autocal_entry *iq_autocal;
400	union p54_scan_body_union *body;
401	struct p54_scan_tail_rate *rate;
402	struct pda_rssi_cal_entry *rssi;
403	struct p54_rssi_db_entry *rssi_data;
404	unsigned int i;
405	void *entry;
406	__le16 freq = cpu_to_le16(priv->hw->conf.chandef.chan->center_freq);
407
408	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*head) +
409			    2 + sizeof(*iq_autocal) + sizeof(*body) +
410			    sizeof(*rate) + 2 * sizeof(*rssi),
411			    P54_CONTROL_TYPE_SCAN, GFP_ATOMIC);
412	if (!skb)
413		return -ENOMEM;
414
415	head = skb_put(skb, sizeof(*head));
416	memset(head->scan_params, 0, sizeof(head->scan_params));
417	head->mode = cpu_to_le16(mode);
418	head->dwell = cpu_to_le16(dwell);
419	head->freq = freq;
420
421	if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
422		__le16 *pa_power_points = skb_put(skb, 2);
423		*pa_power_points = cpu_to_le16(0x0c);
424	}
425
426	iq_autocal = skb_put(skb, sizeof(*iq_autocal));
427	for (i = 0; i < priv->iq_autocal_len; i++) {
428		if (priv->iq_autocal[i].freq != freq)
429			continue;
430
431		memcpy(iq_autocal, &priv->iq_autocal[i].params,
432		       sizeof(struct p54_iq_autocal_entry));
433		break;
434	}
435	if (i == priv->iq_autocal_len)
436		goto err;
437
438	if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW)
439		body = skb_put(skb, sizeof(body->longbow));
440	else
441		body = skb_put(skb, sizeof(body->normal));
442
443	for (i = 0; i < priv->output_limit->entries; i++) {
444		__le16 *entry_freq = (void *) (priv->output_limit->data +
445				     priv->output_limit->entry_size * i);
446
447		if (*entry_freq != freq)
448			continue;
449
450		if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
451			memcpy(&body->longbow.power_limits,
452			       (void *) entry_freq + sizeof(__le16),
453			       priv->output_limit->entry_size);
454		} else {
455			struct pda_channel_output_limit *limits =
456			       (void *) entry_freq;
457
458			body->normal.val_barker = 0x38;
459			body->normal.val_bpsk = body->normal.dup_bpsk =
460				limits->val_bpsk;
461			body->normal.val_qpsk = body->normal.dup_qpsk =
462				limits->val_qpsk;
463			body->normal.val_16qam = body->normal.dup_16qam =
464				limits->val_16qam;
465			body->normal.val_64qam = body->normal.dup_64qam =
466				limits->val_64qam;
467		}
468		break;
469	}
470	if (i == priv->output_limit->entries)
471		goto err;
472
473	entry = (void *)(priv->curve_data->data + priv->curve_data->offset);
474	for (i = 0; i < priv->curve_data->entries; i++) {
475		if (*((__le16 *)entry) != freq) {
476			entry += priv->curve_data->entry_size;
477			continue;
478		}
479
480		if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
481			memcpy(&body->longbow.curve_data,
482				entry + sizeof(__le16),
483				priv->curve_data->entry_size);
484		} else {
485			struct p54_scan_body *chan = &body->normal;
486			struct pda_pa_curve_data *curve_data =
487				(void *) priv->curve_data->data;
488
489			entry += sizeof(__le16);
490			chan->pa_points_per_curve = 8;
491			memset(chan->curve_data, 0, sizeof(chan->curve_data));
492			memcpy(chan->curve_data, entry,
493			       sizeof(struct p54_pa_curve_data_sample) *
494			       min((u8)8, curve_data->points_per_channel));
495		}
496		break;
497	}
498	if (i == priv->curve_data->entries)
499		goto err;
500
501	if ((priv->fw_var >= 0x500) && (priv->fw_var < 0x509)) {
502		rate = skb_put(skb, sizeof(*rate));
503		rate->basic_rate_mask = cpu_to_le32(priv->basic_rate_mask);
504		for (i = 0; i < sizeof(rate->rts_rates); i++)
505			rate->rts_rates[i] = i;
506	}
507
508	rssi = skb_put(skb, sizeof(*rssi));
509	rssi_data = p54_rssi_find(priv, le16_to_cpu(freq));
510	rssi->mul = cpu_to_le16(rssi_data->mul);
511	rssi->add = cpu_to_le16(rssi_data->add);
512	if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
513		/* Longbow frontend needs ever more */
514		rssi = skb_put(skb, sizeof(*rssi));
515		rssi->mul = cpu_to_le16(rssi_data->longbow_unkn);
516		rssi->add = cpu_to_le16(rssi_data->longbow_unk2);
517	}
518
519	if (priv->fw_var >= 0x509) {
520		rate = skb_put(skb, sizeof(*rate));
521		rate->basic_rate_mask = cpu_to_le32(priv->basic_rate_mask);
522		for (i = 0; i < sizeof(rate->rts_rates); i++)
523			rate->rts_rates[i] = i;
524	}
525
526	hdr = (struct p54_hdr *) skb->data;
527	hdr->len = cpu_to_le16(skb->len - sizeof(*hdr));
528
529	p54_tx(priv, skb);
530	priv->cur_rssi = rssi_data;
531	return 0;
532
533err:
534	wiphy_err(priv->hw->wiphy, "frequency change to channel %d failed.\n",
535		  ieee80211_frequency_to_channel(
536			  priv->hw->conf.chandef.chan->center_freq));
537
538	dev_kfree_skb_any(skb);
539	return -EINVAL;
540}
541
542int p54_set_leds(struct p54_common *priv)
543{
544	struct sk_buff *skb;
545	struct p54_led *led;
546
547	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*led),
548			    P54_CONTROL_TYPE_LED, GFP_ATOMIC);
549	if (unlikely(!skb))
550		return -ENOMEM;
551
552	led = skb_put(skb, sizeof(*led));
553	led->flags = cpu_to_le16(0x0003);
554	led->mask[0] = led->mask[1] = cpu_to_le16(priv->softled_state);
555	led->delay[0] = cpu_to_le16(1);
556	led->delay[1] = cpu_to_le16(0);
557	p54_tx(priv, skb);
558	return 0;
559}
560
561int p54_set_edcf(struct p54_common *priv)
562{
563	struct sk_buff *skb;
564	struct p54_edcf *edcf;
565	u8 rtd;
566
567	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*edcf),
568			    P54_CONTROL_TYPE_DCFINIT, GFP_ATOMIC);
569	if (unlikely(!skb))
570		return -ENOMEM;
571
572	edcf = skb_put(skb, sizeof(*edcf));
573	if (priv->use_short_slot) {
574		edcf->slottime = 9;
575		edcf->sifs = 0x10;
576		edcf->eofpad = 0x00;
577	} else {
578		edcf->slottime = 20;
579		edcf->sifs = 0x0a;
580		edcf->eofpad = 0x06;
581	}
582	/*
583	 * calculate the extra round trip delay according to the
584	 * formula from 802.11-2007 17.3.8.6.
585	 */
586	rtd = 3 * priv->coverage_class;
587	edcf->slottime += rtd;
588	edcf->round_trip_delay = cpu_to_le16(rtd);
589	/* (see prism54/isl_oid.h for further details) */
590	edcf->frameburst = cpu_to_le16(0);
591	edcf->flags = 0;
592	memset(edcf->mapping, 0, sizeof(edcf->mapping));
593	memcpy(edcf->queue, priv->qos_params, sizeof(edcf->queue));
594	p54_tx(priv, skb);
595	return 0;
596}
597
598int p54_set_ps(struct p54_common *priv)
599{
600	struct sk_buff *skb;
601	struct p54_psm *psm;
602	unsigned int i;
603	u16 mode;
604
605	if (priv->hw->conf.flags & IEEE80211_CONF_PS &&
606	    !priv->powersave_override)
607		mode = P54_PSM | P54_PSM_BEACON_TIMEOUT | P54_PSM_DTIM |
608		       P54_PSM_CHECKSUM | P54_PSM_MCBC;
609	else
610		mode = P54_PSM_CAM;
611
612	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*psm),
613			    P54_CONTROL_TYPE_PSM, GFP_ATOMIC);
614	if (!skb)
615		return -ENOMEM;
616
617	psm = skb_put(skb, sizeof(*psm));
618	psm->mode = cpu_to_le16(mode);
619	psm->aid = cpu_to_le16(priv->aid);
620	for (i = 0; i < ARRAY_SIZE(psm->intervals); i++) {
621		psm->intervals[i].interval =
622			cpu_to_le16(priv->hw->conf.listen_interval);
623		psm->intervals[i].periods = cpu_to_le16(1);
624	}
625
626	psm->beacon_rssi_skip_max = 200;
627	psm->rssi_delta_threshold = 0;
628	psm->nr = 1;
629	psm->exclude[0] = WLAN_EID_TIM;
630
631	p54_tx(priv, skb);
632	priv->phy_ps = mode != P54_PSM_CAM;
633	return 0;
634}
635
636int p54_init_xbow_synth(struct p54_common *priv)
637{
638	struct sk_buff *skb;
639	struct p54_xbow_synth *xbow;
640
641	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*xbow),
642			    P54_CONTROL_TYPE_XBOW_SYNTH_CFG, GFP_KERNEL);
643	if (unlikely(!skb))
644		return -ENOMEM;
645
646	xbow = skb_put(skb, sizeof(*xbow));
647	xbow->magic1 = cpu_to_le16(0x1);
648	xbow->magic2 = cpu_to_le16(0x2);
649	xbow->freq = cpu_to_le16(5390);
650	memset(xbow->padding, 0, sizeof(xbow->padding));
651	p54_tx(priv, skb);
652	return 0;
653}
654
655int p54_upload_key(struct p54_common *priv, u8 algo, int slot, u8 idx, u8 len,
656		   u8 *addr, u8* key)
657{
658	struct sk_buff *skb;
659	struct p54_keycache *rxkey;
660
661	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*rxkey),
662			    P54_CONTROL_TYPE_RX_KEYCACHE, GFP_KERNEL);
663	if (unlikely(!skb))
664		return -ENOMEM;
665
666	rxkey = skb_put(skb, sizeof(*rxkey));
667	rxkey->entry = slot;
668	rxkey->key_id = idx;
669	rxkey->key_type = algo;
670	if (addr)
671		memcpy(rxkey->mac, addr, ETH_ALEN);
672	else
673		eth_broadcast_addr(rxkey->mac);
674
675	switch (algo) {
676	case P54_CRYPTO_WEP:
677	case P54_CRYPTO_AESCCMP:
678		rxkey->key_len = min_t(u8, 16, len);
679		memcpy(rxkey->key, key, rxkey->key_len);
680		break;
681
682	case P54_CRYPTO_TKIPMICHAEL:
683		rxkey->key_len = 24;
684		memcpy(rxkey->key, key, 16);
685		memcpy(&(rxkey->key[16]), &(key
686			[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY]), 8);
687		break;
688
689	case P54_CRYPTO_NONE:
690		rxkey->key_len = 0;
691		memset(rxkey->key, 0, sizeof(rxkey->key));
692		break;
693
694	default:
695		wiphy_err(priv->hw->wiphy,
696			  "invalid cryptographic algorithm: %d\n", algo);
697		dev_kfree_skb(skb);
698		return -EINVAL;
699	}
700
701	p54_tx(priv, skb);
702	return 0;
703}
704
705int p54_fetch_statistics(struct p54_common *priv)
706{
707	struct ieee80211_tx_info *txinfo;
708	struct p54_tx_info *p54info;
709	struct sk_buff *skb;
710
711	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL,
712			    sizeof(struct p54_statistics),
713			    P54_CONTROL_TYPE_STAT_READBACK, GFP_KERNEL);
714	if (!skb)
715		return -ENOMEM;
716
717	/*
718	 * The statistic feedback causes some extra headaches here, if it
719	 * is not to crash/corrupt the firmware data structures.
720	 *
721	 * Unlike all other Control Get OIDs we can not use helpers like
722	 * skb_put to reserve the space for the data we're requesting.
723	 * Instead the extra frame length -which will hold the results later-
724	 * will only be told to the p54_assign_address, so that following
725	 * frames won't be placed into the  allegedly empty area.
726	 */
727	txinfo = IEEE80211_SKB_CB(skb);
728	p54info = (void *) txinfo->rate_driver_data;
729	p54info->extra_len = sizeof(struct p54_statistics);
730
731	p54_tx(priv, skb);
732	return 0;
733}
734
735int p54_set_groupfilter(struct p54_common *priv)
736{
737	struct p54_group_address_table *grp;
738	struct sk_buff *skb;
739	bool on = false;
740
741	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*grp),
742			    P54_CONTROL_TYPE_GROUP_ADDRESS_TABLE, GFP_KERNEL);
743	if (!skb)
744		return -ENOMEM;
745
746	grp = skb_put(skb, sizeof(*grp));
747
748	on = !(priv->filter_flags & FIF_ALLMULTI) &&
749	     (priv->mc_maclist_num > 0 &&
750	      priv->mc_maclist_num <= MC_FILTER_ADDRESS_NUM);
751
752	if (on) {
753		grp->filter_enable = cpu_to_le16(1);
754		grp->num_address = cpu_to_le16(priv->mc_maclist_num);
755		memcpy(grp->mac_list, priv->mc_maclist, sizeof(grp->mac_list));
756	} else {
757		grp->filter_enable = cpu_to_le16(0);
758		grp->num_address = cpu_to_le16(0);
759		memset(grp->mac_list, 0, sizeof(grp->mac_list));
760	}
761
762	p54_tx(priv, skb);
763	return 0;
764}