mwl8k.c 137 KB
Newer Older
1
/*
2
3
 * drivers/net/wireless/mwl8k.c
 * Driver for Marvell TOPDOG 802.11 Wireless cards
4
 *
5
 * Copyright (C) 2008, 2009, 2010 Marvell Semiconductor Inc.
6
7
8
9
10
11
12
13
14
 *
 * This file is licensed under the terms of the GNU General Public
 * License version 2.  This program is licensed "as is" without any
 * warranty of any kind, whether express or implied.
 */

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
15
#include <linux/sched.h>
16
17
18
19
20
21
#include <linux/spinlock.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/completion.h>
#include <linux/etherdevice.h>
22
#include <linux/slab.h>
23
24
25
26
27
28
29
#include <net/mac80211.h>
#include <linux/moduleparam.h>
#include <linux/firmware.h>
#include <linux/workqueue.h>

#define MWL8K_DESC	"Marvell TOPDOG(R) 802.11 Wireless Network Driver"
#define MWL8K_NAME	KBUILD_MODNAME
30
#define MWL8K_VERSION	"0.12"
31

32
33
34
35
36
37
/* Module parameters */
static unsigned ap_mode_default;
module_param(ap_mode_default, bool, 0);
MODULE_PARM_DESC(ap_mode_default,
		 "Set to 1 to make ap mode the default instead of sta mode");

38
39
/* Register definitions */
#define MWL8K_HIU_GEN_PTR			0x00000c10
40
41
#define  MWL8K_MODE_STA				 0x0000005a
#define  MWL8K_MODE_AP				 0x000000a5
42
#define MWL8K_HIU_INT_CODE			0x00000c14
43
44
45
#define  MWL8K_FWSTA_READY			 0xf0f1f2f4
#define  MWL8K_FWAP_READY			 0xf1f2f4a5
#define  MWL8K_INT_CODE_CMD_FINISHED		 0x00000005
46
47
48
49
50
51
52
53
#define MWL8K_HIU_SCRATCH			0x00000c40

/* Host->device communications */
#define MWL8K_HIU_H2A_INTERRUPT_EVENTS		0x00000c18
#define MWL8K_HIU_H2A_INTERRUPT_STATUS		0x00000c1c
#define MWL8K_HIU_H2A_INTERRUPT_MASK		0x00000c20
#define MWL8K_HIU_H2A_INTERRUPT_CLEAR_SEL	0x00000c24
#define MWL8K_HIU_H2A_INTERRUPT_STATUS_MASK	0x00000c28
54
55
56
57
#define  MWL8K_H2A_INT_DUMMY			 (1 << 20)
#define  MWL8K_H2A_INT_RESET			 (1 << 15)
#define  MWL8K_H2A_INT_DOORBELL			 (1 << 1)
#define  MWL8K_H2A_INT_PPA_READY		 (1 << 0)
58
59
60
61
62
63
64

/* Device->host communications */
#define MWL8K_HIU_A2H_INTERRUPT_EVENTS		0x00000c2c
#define MWL8K_HIU_A2H_INTERRUPT_STATUS		0x00000c30
#define MWL8K_HIU_A2H_INTERRUPT_MASK		0x00000c34
#define MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL	0x00000c38
#define MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK	0x00000c3c
65
#define  MWL8K_A2H_INT_DUMMY			 (1 << 20)
66
#define  MWL8K_A2H_INT_BA_WATCHDOG		 (1 << 14)
67
68
69
70
71
72
73
74
75
#define  MWL8K_A2H_INT_CHNL_SWITCHED		 (1 << 11)
#define  MWL8K_A2H_INT_QUEUE_EMPTY		 (1 << 10)
#define  MWL8K_A2H_INT_RADAR_DETECT		 (1 << 7)
#define  MWL8K_A2H_INT_RADIO_ON			 (1 << 6)
#define  MWL8K_A2H_INT_RADIO_OFF		 (1 << 5)
#define  MWL8K_A2H_INT_MAC_EVENT		 (1 << 3)
#define  MWL8K_A2H_INT_OPC_DONE			 (1 << 2)
#define  MWL8K_A2H_INT_RX_READY			 (1 << 1)
#define  MWL8K_A2H_INT_TX_DONE			 (1 << 0)
76
77
78
79
80
81
82
83
84
85

#define MWL8K_A2H_EVENTS	(MWL8K_A2H_INT_DUMMY | \
				 MWL8K_A2H_INT_CHNL_SWITCHED | \
				 MWL8K_A2H_INT_QUEUE_EMPTY | \
				 MWL8K_A2H_INT_RADAR_DETECT | \
				 MWL8K_A2H_INT_RADIO_ON | \
				 MWL8K_A2H_INT_RADIO_OFF | \
				 MWL8K_A2H_INT_MAC_EVENT | \
				 MWL8K_A2H_INT_OPC_DONE | \
				 MWL8K_A2H_INT_RX_READY | \
86
87
				 MWL8K_A2H_INT_TX_DONE | \
				 MWL8K_A2H_INT_BA_WATCHDOG)
88
89

#define MWL8K_RX_QUEUES		1
90
#define MWL8K_TX_WMM_QUEUES	4
91
#define MWL8K_MAX_AMPDU_QUEUES	8
92
93
#define MWL8K_MAX_TX_QUEUES	(MWL8K_TX_WMM_QUEUES + MWL8K_MAX_AMPDU_QUEUES)
#define mwl8k_tx_queues(priv)	(MWL8K_TX_WMM_QUEUES + (priv)->num_ampdu_queues)
94

95
96
97
98
struct rxd_ops {
	int rxd_size;
	void (*rxd_init)(void *rxd, dma_addr_t next_dma_addr);
	void (*rxd_refill)(void *rxd, dma_addr_t addr, int len);
99
	int (*rxd_process)(void *rxd, struct ieee80211_rx_status *status,
100
			   __le16 *qos, s8 *noise);
101
102
};

103
struct mwl8k_device_info {
104
105
	char *part_name;
	char *helper_image;
106
107
	char *fw_image_sta;
	char *fw_image_ap;
108
	struct rxd_ops *ap_rxd_ops;
109
	u32 fw_api_ap;
110
111
};

112
struct mwl8k_rx_queue {
113
	int rxd_count;
114
115

	/* hw receives here */
116
	int head;
117
118

	/* refill descs here */
119
	int tail;
120

121
	void *rxd;
122
	dma_addr_t rxd_dma;
123
124
	struct {
		struct sk_buff *skb;
125
		DEFINE_DMA_UNMAP_ADDR(dma);
126
	} *buf;
127
128
129
130
};

struct mwl8k_tx_queue {
	/* hw transmits here */
131
	int head;
132
133

	/* sw appends here */
134
	int tail;
135

136
	unsigned int len;
137
138
139
	struct mwl8k_tx_desc *txd;
	dma_addr_t txd_dma;
	struct sk_buff **skb;
140
141
};

142
143
144
145
146
147
148
enum {
	AMPDU_NO_STREAM,
	AMPDU_STREAM_NEW,
	AMPDU_STREAM_IN_PROGRESS,
	AMPDU_STREAM_ACTIVE,
};

149
150
151
152
153
154
155
156
struct mwl8k_ampdu_stream {
	struct ieee80211_sta *sta;
	u8 tid;
	u8 state;
	u8 idx;
	u8 txq_idx; /* index of this stream in priv->txq */
};

157
158
159
struct mwl8k_priv {
	struct ieee80211_hw *hw;
	struct pci_dev *pdev;
160
	int irq;
161

162
163
	struct mwl8k_device_info *device_info;

164
165
166
167
	void __iomem *sram;
	void __iomem *regs;

	/* firmware */
168
169
	const struct firmware *fw_helper;
	const struct firmware *fw_ucode;
170

171
172
173
	/* hardware/firmware parameters */
	bool ap_fw;
	struct rxd_ops *rxd_ops;
174
175
176
	struct ieee80211_supported_band band_24;
	struct ieee80211_channel channels_24[14];
	struct ieee80211_rate rates_24[14];
177
178
179
	struct ieee80211_supported_band band_50;
	struct ieee80211_channel channels_50[4];
	struct ieee80211_rate rates_50[9];
180
181
	u32 ap_macids_supported;
	u32 sta_macids_supported;
182

183
184
	/* Ampdu stream information */
	u8 num_ampdu_queues;
185
186
	spinlock_t stream_lock;
	struct mwl8k_ampdu_stream ampdu[MWL8K_MAX_AMPDU_QUEUES];
187
	struct work_struct watchdog_ba_handle;
188

189
190
191
192
193
194
	/* firmware access */
	struct mutex fw_mutex;
	struct task_struct *fw_mutex_owner;
	int fw_mutex_depth;
	struct completion *hostcmd_wait;

195
196
197
	/* lock held over TX and TX reap */
	spinlock_t tx_lock;

198
199
200
	/* TX quiesce completion, protected by fw_mutex and tx_lock */
	struct completion *tx_wait;

201
	/* List of interfaces.  */
202
	u32 macids_used;
203
	struct list_head vif_list;
204
205
206
207
208
209
210

	/* power management status cookie from firmware */
	u32 *cookie;
	dma_addr_t cookie_dma;

	u16 num_mcaddrs;
	u8 hw_rev;
211
	u32 fw_rev;
212
213
214
215
216
217
218
219

	/*
	 * Running count of TX packets in flight, to avoid
	 * iterating over the transmit rings each time.
	 */
	int pending_tx_pkts;

	struct mwl8k_rx_queue rxq[MWL8K_RX_QUEUES];
220
221
	struct mwl8k_tx_queue txq[MWL8K_MAX_TX_QUEUES];
	u32 txq_offset[MWL8K_MAX_TX_QUEUES];
222

223
	bool radio_on;
224
	bool radio_short_preamble;
225
	bool sniffer_enabled;
226
	bool wmm_enabled;
227
228
229

	/* XXX need to convert this to handle multiple interfaces */
	bool capture_beacon;
230
	u8 capture_bssid[ETH_ALEN];
231
232
233
234
235
236
237
238
239
240
	struct sk_buff *beacon_skb;

	/*
	 * This FJ worker has to be global as it is scheduled from the
	 * RX handler.  At this point we don't know which interface it
	 * belongs to until the list of bssids waiting to complete join
	 * is checked.
	 */
	struct work_struct finalize_join_worker;

241
242
	/* Tasklet to perform TX reclaim.  */
	struct tasklet_struct poll_tx_task;
243
244
245

	/* Tasklet to perform RX.  */
	struct tasklet_struct poll_rx_task;
246
247
248

	/* Most recently reported noise in dBm */
	s8 noise;
249
250
251
252
253

	/*
	 * preserve the queue configurations so they can be restored if/when
	 * the firmware image is swapped.
	 */
254
	struct ieee80211_tx_queue_params wmm_params[MWL8K_TX_WMM_QUEUES];
255
256
257
258
259
260

	/* async firmware loading state */
	unsigned fw_state;
	char *fw_pref;
	char *fw_alt;
	struct completion firmware_loading_complete;
261
262
};

263
264
265
#define MAX_WEP_KEY_LEN         13
#define NUM_WEP_KEYS            4

266
267
/* Per interface specific private data */
struct mwl8k_vif {
268
269
270
	struct list_head list;
	struct ieee80211_vif *vif;

271
272
273
	/* Firmware macid for this vif.  */
	int macid;

Lennert Buytenhek's avatar
Lennert Buytenhek committed
274
	/* Non AMPDU sequence number assigned by driver.  */
275
	u16 seqno;
276
277
278
279
280
281

	/* Saved WEP keys */
	struct {
		u8 enabled;
		u8 key[sizeof(struct ieee80211_key_conf) + MAX_WEP_KEY_LEN];
	} wep_key_conf[NUM_WEP_KEYS];
282
283
284
285
286
287

	/* BSSID */
	u8 bssid[ETH_ALEN];

	/* A flag to indicate is HW crypto is enabled for this bssid */
	bool is_hw_crypto_enabled;
288
};
289
#define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv))
290
#define IEEE80211_KEY_CONF(_u8) ((struct ieee80211_key_conf *)(_u8))
291

292
293
294
295
296
297
struct tx_traffic_info {
	u32 start_time;
	u32 pkts;
};

#define MWL8K_MAX_TID 8
298
299
300
struct mwl8k_sta {
	/* Index into station database. Returned by UPDATE_STADB.  */
	u8 peer_id;
301
	u8 is_ampdu_allowed;
302
	struct tx_traffic_info tx_stats[MWL8K_MAX_TID];
303
304
305
};
#define MWL8K_STA(_sta) ((struct mwl8k_sta *)&((_sta)->drv_priv))

306
static const struct ieee80211_channel mwl8k_channels_24[] = {
307
308
309
310
311
312
313
314
315
316
317
	{ .center_freq = 2412, .hw_value = 1, },
	{ .center_freq = 2417, .hw_value = 2, },
	{ .center_freq = 2422, .hw_value = 3, },
	{ .center_freq = 2427, .hw_value = 4, },
	{ .center_freq = 2432, .hw_value = 5, },
	{ .center_freq = 2437, .hw_value = 6, },
	{ .center_freq = 2442, .hw_value = 7, },
	{ .center_freq = 2447, .hw_value = 8, },
	{ .center_freq = 2452, .hw_value = 9, },
	{ .center_freq = 2457, .hw_value = 10, },
	{ .center_freq = 2462, .hw_value = 11, },
318
319
320
	{ .center_freq = 2467, .hw_value = 12, },
	{ .center_freq = 2472, .hw_value = 13, },
	{ .center_freq = 2484, .hw_value = 14, },
321
322
};

323
static const struct ieee80211_rate mwl8k_rates_24[] = {
324
325
326
	{ .bitrate = 10, .hw_value = 2, },
	{ .bitrate = 20, .hw_value = 4, },
	{ .bitrate = 55, .hw_value = 11, },
327
328
	{ .bitrate = 110, .hw_value = 22, },
	{ .bitrate = 220, .hw_value = 44, },
329
330
331
332
333
334
335
336
	{ .bitrate = 60, .hw_value = 12, },
	{ .bitrate = 90, .hw_value = 18, },
	{ .bitrate = 120, .hw_value = 24, },
	{ .bitrate = 180, .hw_value = 36, },
	{ .bitrate = 240, .hw_value = 48, },
	{ .bitrate = 360, .hw_value = 72, },
	{ .bitrate = 480, .hw_value = 96, },
	{ .bitrate = 540, .hw_value = 108, },
337
338
339
	{ .bitrate = 720, .hw_value = 144, },
};

340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
static const struct ieee80211_channel mwl8k_channels_50[] = {
	{ .center_freq = 5180, .hw_value = 36, },
	{ .center_freq = 5200, .hw_value = 40, },
	{ .center_freq = 5220, .hw_value = 44, },
	{ .center_freq = 5240, .hw_value = 48, },
};

static const struct ieee80211_rate mwl8k_rates_50[] = {
	{ .bitrate = 60, .hw_value = 12, },
	{ .bitrate = 90, .hw_value = 18, },
	{ .bitrate = 120, .hw_value = 24, },
	{ .bitrate = 180, .hw_value = 36, },
	{ .bitrate = 240, .hw_value = 48, },
	{ .bitrate = 360, .hw_value = 72, },
	{ .bitrate = 480, .hw_value = 96, },
	{ .bitrate = 540, .hw_value = 108, },
	{ .bitrate = 720, .hw_value = 144, },
};

359
360
/* Set or get info from Firmware */
#define MWL8K_CMD_GET			0x0000
361
362
#define MWL8K_CMD_SET			0x0001
#define MWL8K_CMD_SET_LIST		0x0002
363
364
365
366

/* Firmware command codes */
#define MWL8K_CMD_CODE_DNLD		0x0001
#define MWL8K_CMD_GET_HW_SPEC		0x0003
367
#define MWL8K_CMD_SET_HW_SPEC		0x0004
368
369
#define MWL8K_CMD_MAC_MULTICAST_ADR	0x0010
#define MWL8K_CMD_GET_STAT		0x0014
370
371
#define MWL8K_CMD_RADIO_CONTROL		0x001c
#define MWL8K_CMD_RF_TX_POWER		0x001e
372
#define MWL8K_CMD_TX_POWER		0x001f
373
#define MWL8K_CMD_RF_ANTENNA		0x0020
374
#define MWL8K_CMD_SET_BEACON		0x0100		/* per-vif */
375
376
#define MWL8K_CMD_SET_PRE_SCAN		0x0107
#define MWL8K_CMD_SET_POST_SCAN		0x0108
377
378
379
380
381
#define MWL8K_CMD_SET_RF_CHANNEL	0x010a
#define MWL8K_CMD_SET_AID		0x010d
#define MWL8K_CMD_SET_RATE		0x0110
#define MWL8K_CMD_SET_FINALIZE_JOIN	0x0111
#define MWL8K_CMD_RTS_THRESHOLD		0x0113
382
#define MWL8K_CMD_SET_SLOT		0x0114
383
384
#define MWL8K_CMD_SET_EDCA_PARAMS	0x0115
#define MWL8K_CMD_SET_WMM_MODE		0x0123
385
#define MWL8K_CMD_MIMO_CONFIG		0x0125
386
#define MWL8K_CMD_USE_FIXED_RATE	0x0126
387
#define MWL8K_CMD_ENABLE_SNIFFER	0x0150
388
#define MWL8K_CMD_SET_MAC_ADDR		0x0202		/* per-vif */
389
#define MWL8K_CMD_SET_RATEADAPT_MODE	0x0203
390
#define MWL8K_CMD_GET_WATCHDOG_BITMAP	0x0205
391
392
#define MWL8K_CMD_BSS_START		0x1100		/* per-vif */
#define MWL8K_CMD_SET_NEW_STN		0x1111		/* per-vif */
393
#define MWL8K_CMD_UPDATE_ENCRYPTION	0x1122		/* per-vif */
394
#define MWL8K_CMD_UPDATE_STADB		0x1123
395
#define MWL8K_CMD_BASTREAM		0x1125
396

397
static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize)
398
{
399
400
	u16 command = le16_to_cpu(cmd);

401
402
403
404
#define MWL8K_CMDNAME(x)	case MWL8K_CMD_##x: do {\
					snprintf(buf, bufsize, "%s", #x);\
					return buf;\
					} while (0)
405
	switch (command & ~0x8000) {
406
407
		MWL8K_CMDNAME(CODE_DNLD);
		MWL8K_CMDNAME(GET_HW_SPEC);
408
		MWL8K_CMDNAME(SET_HW_SPEC);
409
410
411
412
		MWL8K_CMDNAME(MAC_MULTICAST_ADR);
		MWL8K_CMDNAME(GET_STAT);
		MWL8K_CMDNAME(RADIO_CONTROL);
		MWL8K_CMDNAME(RF_TX_POWER);
413
		MWL8K_CMDNAME(TX_POWER);
414
		MWL8K_CMDNAME(RF_ANTENNA);
415
		MWL8K_CMDNAME(SET_BEACON);
416
417
418
		MWL8K_CMDNAME(SET_PRE_SCAN);
		MWL8K_CMDNAME(SET_POST_SCAN);
		MWL8K_CMDNAME(SET_RF_CHANNEL);
419
420
421
422
		MWL8K_CMDNAME(SET_AID);
		MWL8K_CMDNAME(SET_RATE);
		MWL8K_CMDNAME(SET_FINALIZE_JOIN);
		MWL8K_CMDNAME(RTS_THRESHOLD);
423
		MWL8K_CMDNAME(SET_SLOT);
424
425
		MWL8K_CMDNAME(SET_EDCA_PARAMS);
		MWL8K_CMDNAME(SET_WMM_MODE);
426
		MWL8K_CMDNAME(MIMO_CONFIG);
427
		MWL8K_CMDNAME(USE_FIXED_RATE);
428
		MWL8K_CMDNAME(ENABLE_SNIFFER);
429
		MWL8K_CMDNAME(SET_MAC_ADDR);
430
		MWL8K_CMDNAME(SET_RATEADAPT_MODE);
431
		MWL8K_CMDNAME(BSS_START);
432
		MWL8K_CMDNAME(SET_NEW_STN);
433
		MWL8K_CMDNAME(UPDATE_ENCRYPTION);
434
		MWL8K_CMDNAME(UPDATE_STADB);
435
		MWL8K_CMDNAME(BASTREAM);
436
		MWL8K_CMDNAME(GET_WATCHDOG_BITMAP);
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
	default:
		snprintf(buf, bufsize, "0x%x", cmd);
	}
#undef MWL8K_CMDNAME

	return buf;
}

/* Hardware and firmware reset */
static void mwl8k_hw_reset(struct mwl8k_priv *priv)
{
	iowrite32(MWL8K_H2A_INT_RESET,
		priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
	iowrite32(MWL8K_H2A_INT_RESET,
		priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
	msleep(20);
}

/* Release fw image */
456
static void mwl8k_release_fw(const struct firmware **fw)
457
458
459
460
461
462
463
464
465
{
	if (*fw == NULL)
		return;
	release_firmware(*fw);
	*fw = NULL;
}

static void mwl8k_release_firmware(struct mwl8k_priv *priv)
{
466
467
	mwl8k_release_fw(&priv->fw_ucode);
	mwl8k_release_fw(&priv->fw_helper);
468
469
}

470
471
472
473
474
475
476
477
478
/* states for asynchronous f/w loading */
static void mwl8k_fw_state_machine(const struct firmware *fw, void *context);
enum {
	FW_STATE_INIT = 0,
	FW_STATE_LOADING_PREF,
	FW_STATE_LOADING_ALT,
	FW_STATE_ERROR,
};

479
480
/* Request fw image */
static int mwl8k_request_fw(struct mwl8k_priv *priv,
481
			    const char *fname, const struct firmware **fw,
482
			    bool nowait)
483
484
485
486
487
{
	/* release current image */
	if (*fw != NULL)
		mwl8k_release_fw(fw);

488
489
490
491
492
	if (nowait)
		return request_firmware_nowait(THIS_MODULE, 1, fname,
					       &priv->pdev->dev, GFP_KERNEL,
					       priv, mwl8k_fw_state_machine);
	else
493
		return request_firmware(fw, fname, &priv->pdev->dev);
494
495
}

496
497
static int mwl8k_request_firmware(struct mwl8k_priv *priv, char *fw_image,
				  bool nowait)
498
{
499
	struct mwl8k_device_info *di = priv->device_info;
500
501
	int rc;

502
	if (di->helper_image != NULL) {
503
504
505
506
507
508
509
510
511
512
513
		if (nowait)
			rc = mwl8k_request_fw(priv, di->helper_image,
					      &priv->fw_helper, true);
		else
			rc = mwl8k_request_fw(priv, di->helper_image,
					      &priv->fw_helper, false);
		if (rc)
			printk(KERN_ERR "%s: Error requesting helper fw %s\n",
			       pci_name(priv->pdev), di->helper_image);

		if (rc || nowait)
514
			return rc;
515
516
	}

517
518
519
520
521
522
523
524
525
526
527
528
	if (nowait) {
		/*
		 * if we get here, no helper image is needed.  Skip the
		 * FW_STATE_INIT state.
		 */
		priv->fw_state = FW_STATE_LOADING_PREF;
		rc = mwl8k_request_fw(priv, fw_image,
				      &priv->fw_ucode,
				      true);
	} else
		rc = mwl8k_request_fw(priv, fw_image,
				      &priv->fw_ucode, false);
529
	if (rc) {
530
		printk(KERN_ERR "%s: Error requesting firmware file %s\n",
531
		       pci_name(priv->pdev), fw_image);
532
		mwl8k_release_fw(&priv->fw_helper);
533
534
535
536
537
538
539
540
541
		return rc;
	}

	return 0;
}

struct mwl8k_cmd_pkt {
	__le16	code;
	__le16	length;
542
543
	__u8	seq_num;
	__u8	macid;
544
545
	__le16	result;
	char	payload[0];
546
} __packed;
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578

/*
 * Firmware loading.
 */
static int
mwl8k_send_fw_load_cmd(struct mwl8k_priv *priv, void *data, int length)
{
	void __iomem *regs = priv->regs;
	dma_addr_t dma_addr;
	int loops;

	dma_addr = pci_map_single(priv->pdev, data, length, PCI_DMA_TODEVICE);
	if (pci_dma_mapping_error(priv->pdev, dma_addr))
		return -ENOMEM;

	iowrite32(dma_addr, regs + MWL8K_HIU_GEN_PTR);
	iowrite32(0, regs + MWL8K_HIU_INT_CODE);
	iowrite32(MWL8K_H2A_INT_DOORBELL,
		regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
	iowrite32(MWL8K_H2A_INT_DUMMY,
		regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);

	loops = 1000;
	do {
		u32 int_code;

		int_code = ioread32(regs + MWL8K_HIU_INT_CODE);
		if (int_code == MWL8K_INT_CODE_CMD_FINISHED) {
			iowrite32(0, regs + MWL8K_HIU_INT_CODE);
			break;
		}

579
		cond_resched();
580
581
582
583
584
		udelay(1);
	} while (--loops);

	pci_unmap_single(priv->pdev, dma_addr, length, PCI_DMA_TODEVICE);

585
	return loops ? 0 : -ETIMEDOUT;
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
}

static int mwl8k_load_fw_image(struct mwl8k_priv *priv,
				const u8 *data, size_t length)
{
	struct mwl8k_cmd_pkt *cmd;
	int done;
	int rc = 0;

	cmd = kmalloc(sizeof(*cmd) + 256, GFP_KERNEL);
	if (cmd == NULL)
		return -ENOMEM;

	cmd->code = cpu_to_le16(MWL8K_CMD_CODE_DNLD);
	cmd->seq_num = 0;
601
	cmd->macid = 0;
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
	cmd->result = 0;

	done = 0;
	while (length) {
		int block_size = length > 256 ? 256 : length;

		memcpy(cmd->payload, data + done, block_size);
		cmd->length = cpu_to_le16(block_size);

		rc = mwl8k_send_fw_load_cmd(priv, cmd,
						sizeof(*cmd) + block_size);
		if (rc)
			break;

		done += block_size;
		length -= block_size;
	}

	if (!rc) {
		cmd->length = 0;
		rc = mwl8k_send_fw_load_cmd(priv, cmd, sizeof(*cmd));
	}

	kfree(cmd);

	return rc;
}

static int mwl8k_feed_fw_image(struct mwl8k_priv *priv,
				const u8 *data, size_t length)
{
	unsigned char *buffer;
	int may_continue, rc = 0;
	u32 done, prev_block_size;

	buffer = kmalloc(1024, GFP_KERNEL);
	if (buffer == NULL)
		return -ENOMEM;

	done = 0;
	prev_block_size = 0;
	may_continue = 1000;
	while (may_continue > 0) {
		u32 block_size;

		block_size = ioread32(priv->regs + MWL8K_HIU_SCRATCH);
		if (block_size & 1) {
			block_size &= ~1;
			may_continue--;
		} else {
			done += prev_block_size;
			length -= prev_block_size;
		}

		if (block_size > 1024 || block_size > length) {
			rc = -EOVERFLOW;
			break;
		}

		if (length == 0) {
			rc = 0;
			break;
		}

		if (block_size == 0) {
			rc = -EPROTO;
			may_continue--;
			udelay(1);
			continue;
		}

		prev_block_size = block_size;
		memcpy(buffer, data + done, block_size);

		rc = mwl8k_send_fw_load_cmd(priv, buffer, block_size);
		if (rc)
			break;
	}

	if (!rc && length != 0)
		rc = -EREMOTEIO;

	kfree(buffer);

	return rc;
}

689
static int mwl8k_load_firmware(struct ieee80211_hw *hw)
690
{
691
	struct mwl8k_priv *priv = hw->priv;
692
	const struct firmware *fw = priv->fw_ucode;
693
694
695
696
	int rc;
	int loops;

	if (!memcmp(fw->data, "\x01\x00\x00\x00", 4)) {
697
		const struct firmware *helper = priv->fw_helper;
698

699
700
701
702
703
		if (helper == NULL) {
			printk(KERN_ERR "%s: helper image needed but none "
			       "given\n", pci_name(priv->pdev));
			return -EINVAL;
		}
704

705
		rc = mwl8k_load_fw_image(priv, helper->data, helper->size);
706
707
		if (rc) {
			printk(KERN_ERR "%s: unable to load firmware "
708
			       "helper image\n", pci_name(priv->pdev));
709
710
			return rc;
		}
711
		msleep(20);
712

713
		rc = mwl8k_feed_fw_image(priv, fw->data, fw->size);
714
	} else {
715
		rc = mwl8k_load_fw_image(priv, fw->data, fw->size);
716
717
718
	}

	if (rc) {
719
720
		printk(KERN_ERR "%s: unable to load firmware image\n",
		       pci_name(priv->pdev));
721
722
723
		return rc;
	}

724
	iowrite32(MWL8K_MODE_STA, priv->regs + MWL8K_HIU_GEN_PTR);
725

726
	loops = 500000;
727
	do {
728
729
730
731
732
733
734
735
		u32 ready_code;

		ready_code = ioread32(priv->regs + MWL8K_HIU_INT_CODE);
		if (ready_code == MWL8K_FWAP_READY) {
			priv->ap_fw = 1;
			break;
		} else if (ready_code == MWL8K_FWSTA_READY) {
			priv->ap_fw = 0;
736
			break;
737
738
739
		}

		cond_resched();
740
741
742
743
744
745
746
747
748
749
750
		udelay(1);
	} while (--loops);

	return loops ? 0 : -ETIMEDOUT;
}


/* DMA header used by firmware and hardware.  */
struct mwl8k_dma_data {
	__le16 fwlen;
	struct ieee80211_hdr wh;
751
	char data[0];
752
} __packed;
753
754

/* Routines to add/remove DMA header from skb.  */
755
static inline void mwl8k_remove_dma_header(struct sk_buff *skb, __le16 qos)
756
{
757
758
759
760
761
762
763
764
765
766
767
768
769
	struct mwl8k_dma_data *tr;
	int hdrlen;

	tr = (struct mwl8k_dma_data *)skb->data;
	hdrlen = ieee80211_hdrlen(tr->wh.frame_control);

	if (hdrlen != sizeof(tr->wh)) {
		if (ieee80211_is_data_qos(tr->wh.frame_control)) {
			memmove(tr->data - hdrlen, &tr->wh, hdrlen - 2);
			*((__le16 *)(tr->data - 2)) = qos;
		} else {
			memmove(tr->data - hdrlen, &tr->wh, hdrlen);
		}
770
	}
771
772
773

	if (hdrlen != sizeof(*tr))
		skb_pull(skb, sizeof(*tr) - hdrlen);
774
775
}

776
777
static void
mwl8k_add_dma_header(struct sk_buff *skb, int tail_pad)
778
779
{
	struct ieee80211_hdr *wh;
780
	int hdrlen;
781
	int reqd_hdrlen;
782
783
	struct mwl8k_dma_data *tr;

784
785
786
787
788
789
	/*
	 * Add a firmware DMA header; the firmware requires that we
	 * present a 2-byte payload length followed by a 4-address
	 * header (without QoS field), followed (optionally) by any
	 * WEP/ExtIV header (but only filled in for CCMP).
	 */
790
	wh = (struct ieee80211_hdr *)skb->data;
791

792
	hdrlen = ieee80211_hdrlen(wh->frame_control);
793
794
795
796
	reqd_hdrlen = sizeof(*tr);

	if (hdrlen != reqd_hdrlen)
		skb_push(skb, reqd_hdrlen - hdrlen);
797

798
	if (ieee80211_is_data_qos(wh->frame_control))
799
		hdrlen -= IEEE80211_QOS_CTL_LEN;
800
801
802
803

	tr = (struct mwl8k_dma_data *)skb->data;
	if (wh != &tr->wh)
		memmove(&tr->wh, wh, hdrlen);
804
805
	if (hdrlen != sizeof(tr->wh))
		memset(((void *)&tr->wh) + hdrlen, 0, sizeof(tr->wh) - hdrlen);
806
807
808
809
810
811

	/*
	 * Firmware length is the length of the fully formed "802.11
	 * payload".  That is, everything except for the 802.11 header.
	 * This includes all crypto material including the MIC.
	 */
812
	tr->fwlen = cpu_to_le16(skb->len - sizeof(*tr) + tail_pad);
813
814
}

815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
static void mwl8k_encapsulate_tx_frame(struct sk_buff *skb)
{
	struct ieee80211_hdr *wh;
	struct ieee80211_tx_info *tx_info;
	struct ieee80211_key_conf *key_conf;
	int data_pad;

	wh = (struct ieee80211_hdr *)skb->data;

	tx_info = IEEE80211_SKB_CB(skb);

	key_conf = NULL;
	if (ieee80211_is_data(wh->frame_control))
		key_conf = tx_info->control.hw_key;

	/*
	 * Make sure the packet header is in the DMA header format (4-address
	 * without QoS), the necessary crypto padding between the header and the
833
834
	 * payload has already been provided by mac80211, but it doesn't add
	 * tail padding when HW crypto is enabled.
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
	 *
	 * We have the following trailer padding requirements:
	 * - WEP: 4 trailer bytes (ICV)
	 * - TKIP: 12 trailer bytes (8 MIC + 4 ICV)
	 * - CCMP: 8 trailer bytes (MIC)
	 */
	data_pad = 0;
	if (key_conf != NULL) {
		switch (key_conf->cipher) {
		case WLAN_CIPHER_SUITE_WEP40:
		case WLAN_CIPHER_SUITE_WEP104:
			data_pad = 4;
			break;
		case WLAN_CIPHER_SUITE_TKIP:
			data_pad = 12;
			break;
		case WLAN_CIPHER_SUITE_CCMP:
			data_pad = 8;
			break;
		}
	}
	mwl8k_add_dma_header(skb, data_pad);
}
858
859

/*
860
 * Packet reception for 88w8366 AP firmware.
861
 */
862
struct mwl8k_rxd_8366_ap {
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
	__le16 pkt_len;
	__u8 sq2;
	__u8 rate;
	__le32 pkt_phys_addr;
	__le32 next_rxd_phys_addr;
	__le16 qos_control;
	__le16 htsig2;
	__le32 hw_rssi_info;
	__le32 hw_noise_floor_info;
	__u8 noise_floor;
	__u8 pad0[3];
	__u8 rssi;
	__u8 rx_status;
	__u8 channel;
	__u8 rx_ctrl;
878
} __packed;
879

880
881
882
#define MWL8K_8366_AP_RATE_INFO_MCS_FORMAT	0x80
#define MWL8K_8366_AP_RATE_INFO_40MHZ		0x40
#define MWL8K_8366_AP_RATE_INFO_RATEID(x)	((x) & 0x3f)
883

884
#define MWL8K_8366_AP_RX_CTRL_OWNED_BY_HOST	0x80
885

886
887
888
889
890
891
892
/* 8366 AP rx_status bits */
#define MWL8K_8366_AP_RXSTAT_DECRYPT_ERR_MASK		0x80
#define MWL8K_8366_AP_RXSTAT_GENERAL_DECRYPT_ERR	0xFF
#define MWL8K_8366_AP_RXSTAT_TKIP_DECRYPT_MIC_ERR	0x02
#define MWL8K_8366_AP_RXSTAT_WEP_DECRYPT_ICV_ERR	0x04
#define MWL8K_8366_AP_RXSTAT_TKIP_DECRYPT_ICV_ERR	0x08

893
static void mwl8k_rxd_8366_ap_init(void *_rxd, dma_addr_t next_dma_addr)
894
{
895
	struct mwl8k_rxd_8366_ap *rxd = _rxd;
896
897

	rxd->next_rxd_phys_addr = cpu_to_le32(next_dma_addr);
898
	rxd->rx_ctrl = MWL8K_8366_AP_RX_CTRL_OWNED_BY_HOST;
899
900
}

901
static void mwl8k_rxd_8366_ap_refill(void *_rxd, dma_addr_t addr, int len)
902
{
903
	struct mwl8k_rxd_8366_ap *rxd = _rxd;
904
905
906
907
908
909
910
911

	rxd->pkt_len = cpu_to_le16(len);
	rxd->pkt_phys_addr = cpu_to_le32(addr);
	wmb();
	rxd->rx_ctrl = 0;
}

static int
912
mwl8k_rxd_8366_ap_process(void *_rxd, struct ieee80211_rx_status *status,
913
			  __le16 *qos, s8 *noise)
914
{
915
	struct mwl8k_rxd_8366_ap *rxd = _rxd;
916

917
	if (!(rxd->rx_ctrl & MWL8K_8366_AP_RX_CTRL_OWNED_BY_HOST))
918
919
920
921
922
923
		return -1;
	rmb();

	memset(status, 0, sizeof(*status));

	status->signal = -rxd->rssi;
924
	*noise = -rxd->noise_floor;
925

926
	if (rxd->rate & MWL8K_8366_AP_RATE_INFO_MCS_FORMAT) {
927
		status->flag |= RX_FLAG_HT;
928
		if (rxd->rate & MWL8K_8366_AP_RATE_INFO_40MHZ)
929
			status->flag |= RX_FLAG_40MHZ;
930
		status->rate_idx = MWL8K_8366_AP_RATE_INFO_RATEID(rxd->rate);
931
932
933
	} else {
		int i;

934
935
		for (i = 0; i < ARRAY_SIZE(mwl8k_rates_24); i++) {
			if (mwl8k_rates_24[i].hw_value == rxd->rate) {
936
937
938
939
940
941
				status->rate_idx = i;
				break;
			}
		}
	}

942
943
944
945
946
947
948
	if (rxd->channel > 14) {
		status->band = IEEE80211_BAND_5GHZ;
		if (!(status->flag & RX_FLAG_HT))
			status->rate_idx -= 5;
	} else {
		status->band = IEEE80211_BAND_2GHZ;
	}
949
950
	status->freq = ieee80211_channel_to_frequency(rxd->channel,
						      status->band);
951

952
953
	*qos = rxd->qos_control;

954
955
956
957
958
	if ((rxd->rx_status != MWL8K_8366_AP_RXSTAT_GENERAL_DECRYPT_ERR) &&
	    (rxd->rx_status & MWL8K_8366_AP_RXSTAT_DECRYPT_ERR_MASK) &&
	    (rxd->rx_status & MWL8K_8366_AP_RXSTAT_TKIP_DECRYPT_MIC_ERR))
		status->flag |= RX_FLAG_MMIC_ERROR;

959
960
961
	return le16_to_cpu(rxd->pkt_len);
}

962
963
964
965
966
static struct rxd_ops rxd_8366_ap_ops = {
	.rxd_size	= sizeof(struct mwl8k_rxd_8366_ap),
	.rxd_init	= mwl8k_rxd_8366_ap_init,
	.rxd_refill	= mwl8k_rxd_8366_ap_refill,
	.rxd_process	= mwl8k_rxd_8366_ap_process,
967
968
969
};

/*
970
 * Packet reception for STA firmware.
971
 */
972
struct mwl8k_rxd_sta {
973
974
975
976
	__le16 pkt_len;
	__u8 link_quality;
	__u8 noise_level;
	__le32 pkt_phys_addr;
977
	__le32 next_rxd_phys_addr;
978
979
980
981
982
983
984
985
986
	__le16 qos_control;
	__le16 rate_info;
	__le32 pad0[4];
	__u8 rssi;
	__u8 channel;
	__le16 pad1;
	__u8 rx_ctrl;
	__u8 rx_status;
	__u8 pad2[2];
987
} __packed;
988

989
990
991
992
993
994
#define MWL8K_STA_RATE_INFO_SHORTPRE		0x8000
#define MWL8K_STA_RATE_INFO_ANTSELECT(x)	(((x) >> 11) & 0x3)
#define MWL8K_STA_RATE_INFO_RATEID(x)		(((x) >> 3) & 0x3f)
#define MWL8K_STA_RATE_INFO_40MHZ		0x0004
#define MWL8K_STA_RATE_INFO_SHORTGI		0x0002
#define MWL8K_STA_RATE_INFO_MCS_FORMAT		0x0001
995

996
#define MWL8K_STA_RX_CTRL_OWNED_BY_HOST		0x02
997
998
999
1000
1001
#define MWL8K_STA_RX_CTRL_DECRYPT_ERROR		0x04
/* ICV=0 or MIC=1 */
#define MWL8K_STA_RX_CTRL_DEC_ERR_TYPE		0x08
/* Key is uploaded only in failure case */
#define MWL8K_STA_RX_CTRL_KEY_INDEX			0x30
1002

1003
static void mwl8k_rxd_sta_init(void *_rxd, dma_addr_t next_dma_addr)
1004
{
1005
	struct mwl8k_rxd_sta *rxd = _rxd;
1006
1007

	rxd->next_rxd_phys_addr = cpu_to_le32(next_dma_addr);
1008
	rxd->rx_ctrl = MWL8K_STA_RX_CTRL_OWNED_BY_HOST;
1009
1010
}

1011
static void mwl8k_rxd_sta_refill(void *_rxd, dma_addr_t addr, int len)
1012
{
1013
	struct mwl8k_rxd_sta *rxd = _rxd;
1014
1015
1016
1017
1018
1019
1020
1021

	rxd->pkt_len = cpu_to_le16(len);
	rxd->pkt_phys_addr = cpu_to_le32(addr);
	wmb();
	rxd->rx_ctrl = 0;
}

static int
1022
mwl8k_rxd_sta_process(void *_rxd, struct ieee80211_rx_status *status,
1023
		       __le16 *qos, s8 *noise)
1024
{
1025
	struct mwl8k_rxd_sta *rxd = _rxd;
1026
1027
	u16 rate_info;

1028
	if (!(rxd->rx_ctrl & MWL8K_STA_RX_CTRL_OWNED_BY_HOST))
1029
1030
1031
1032
1033
1034
1035
1036
		return -1;
	rmb();

	rate_info = le16_to_cpu(rxd->rate_info);

	memset(status, 0, sizeof(*status));

	status->signal = -rxd->rssi;
1037
	*noise = -rxd->noise_level;
1038
1039
	status->antenna = MWL8K_STA_RATE_INFO_ANTSELECT(rate_info);
	status->rate_idx = MWL8K_STA_RATE_INFO_RATEID(rate_info);
1040

1041
	if (rate_info & MWL8K_STA_RATE_INFO_SHORTPRE)
1042
		status->flag |= RX_FLAG_SHORTPRE;
1043
	if (rate_info & MWL8K_STA_RATE_INFO_40MHZ)
1044
		status->flag |= RX_FLAG_40MHZ;
1045
	if (rate_info & MWL8K_STA_RATE_INFO_SHORTGI)
1046
		status->flag |= RX_FLAG_SHORT_GI;
1047
	if (rate_info & MWL8K_STA_RATE_INFO_MCS_FORMAT)
1048
1049
		status->flag |= RX_FLAG_HT;

1050
1051
1052
1053
1054
1055
1056
	if (rxd->channel > 14) {
		status->band = IEEE80211_BAND_5GHZ;
		if (!(status->flag & RX_FLAG_HT))
			status->rate_idx -= 5;
	} else {
		status->band = IEEE80211_BAND_2GHZ;
	}
1057
1058
	status->freq = ieee80211_channel_to_frequency(rxd->channel,
						      status->band);
1059

1060
	*qos = rxd->qos_control;
1061
1062
1063
	if ((rxd->rx_ctrl & MWL8K_STA_RX_CTRL_DECRYPT_ERROR) &&
	    (rxd->rx_ctrl & MWL8K_STA_RX_CTRL_DEC_ERR_TYPE))
		status->flag |= RX_FLAG_MMIC_ERROR;
1064

1065
1066
1067
	return le16_to_cpu(rxd->pkt_len);
}

1068
1069
1070
1071
1072
static struct rxd_ops rxd_sta_ops = {
	.rxd_size	= sizeof(struct mwl8k_rxd_sta),
	.rxd_init	= mwl8k_rxd_sta_init,
	.rxd_refill	= mwl8k_rxd_sta_refill,
	.rxd_process	= mwl8k_rxd_sta_process,
1073
1074
1075
};


1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
#define MWL8K_RX_DESCS		256
#define MWL8K_RX_MAXSZ		3800

static int mwl8k_rxq_init(struct ieee80211_hw *hw, int index)
{
	struct mwl8k_priv *priv = hw->priv;
	struct mwl8k_rx_queue *rxq = priv->rxq + index;
	int size;
	int i;

1086
1087
1088
	rxq->rxd_count = 0;
	rxq->head = 0;
	rxq->tail = 0;
1089

1090
	size = MWL8K_RX_DESCS * priv->rxd_ops->rxd_size;
1091

1092
1093
	rxq->rxd = pci_alloc_consistent(priv->pdev, size, &rxq->rxd_dma);
	if (rxq->rxd == NULL) {
1094
		wiphy_err(hw->wiphy, "failed to alloc RX descriptors\n");
1095
1096
		return -ENOMEM;
	}
1097
	memset(rxq->rxd, 0, size);
1098

1099
	rxq->buf = kcalloc(MWL8K_RX_DESCS, sizeof(*rxq->buf), GFP_KERNEL);
1100
	if (rxq->buf == NULL) {
1101
		wiphy_err(hw->wiphy, "failed to alloc RX skbuff list\n");
1102
		pci_free_consistent(priv->pdev, size, rxq->rxd, rxq->rxd_dma);
1103
1104
1105
1106
		return -ENOMEM;
	}

	for (i = 0; i < MWL8K_RX_DESCS; i++) {
1107
1108
		int desc_size;
		void *rxd;
1109
		int nexti;
1110
1111
1112
1113
		dma_addr_t next_dma_addr;

		desc_size = priv->rxd_ops->rxd_size;
		rxd = rxq->rxd + (i * priv->rxd_ops->rxd_size);
1114

1115
1116
1117
1118
		nexti = i + 1;
		if (nexti == MWL8K_RX_DESCS)
			nexti = 0;
		next_dma_addr = rxq->rxd_dma + (nexti * desc_size);
1119

1120
		priv->rxd_ops->rxd_init(rxd, next_dma_addr);
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
	}

	return 0;
}

static int rxq_refill(struct ieee80211_hw *hw, int index, int limit)
{
	struct mwl8k_priv *priv = hw->priv;
	struct mwl8k_rx_queue *rxq = priv->rxq + index;
	int refilled;

	refilled = 0;
1133
	while (rxq->rxd_count < MWL8K_RX_DESCS && limit--) {
1134
		struct sk_buff *skb;
1135
		dma_addr_t addr;
1136
		int rx;
1137
		void *rxd;
1138
1139
1140
1141
1142

		skb = dev_alloc_skb(MWL8K_RX_MAXSZ);
		if (skb == NULL)
			break;

1143
1144
		addr = pci_map_single(priv->pdev, skb->data,
				      MWL8K_RX_MAXSZ, DMA_FROM_DEVICE);
1145

1146
1147
1148
1149
		rxq->rxd_count++;
		rx = rxq->tail++;
		if (rxq->tail == MWL8K_RX_DESCS)
			rxq->tail = 0;
1150
		rxq->buf[rx].skb = skb;
1151
		dma_unmap_addr_set(&rxq->buf[rx], dma, addr);
1152
1153
1154

		rxd = rxq->rxd + (rx * priv->rxd_ops->rxd_size);
		priv->rxd_ops->rxd_refill(rxd, addr, MWL8K_RX_MAXSZ);
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168

		refilled++;
	}

	return refilled;
}

/* Must be called only when the card's reception is completely halted */
static void mwl8k_rxq_deinit(struct ieee80211_hw *hw, int index)
{
	struct mwl8k_priv *priv = hw->priv;
	struct mwl8k_rx_queue *rxq = priv->rxq + index;
	int i;

1169
1170
1171
	if (rxq->rxd == NULL)
		return;