Пример #1
0
static int ks7010_sdio_update_index(struct ks_wlan_private *priv, u32 index)
{
	int ret;
	unsigned char *data_buf;

	data_buf = kmalloc(sizeof(u32), GFP_KERNEL);
	if (!data_buf)
		return -ENOMEM;

	memcpy(data_buf, &index, sizeof(index));
	ret = ks7010_sdio_write(priv, WRITE_INDEX, data_buf, sizeof(index));
	if (ret)
		goto err_free_data_buf;

	ret = ks7010_sdio_write(priv, READ_INDEX, data_buf, sizeof(index));
	if (ret)
		goto err_free_data_buf;

	return 0;

err_free_data_buf:
	kfree(data_buf);

	return ret;
}
Пример #2
0
/* write data */
static int write_to_device(struct ks_wlan_private *priv, unsigned char *buffer,
			   unsigned long size)
{
	int rc, retval;
	unsigned char rw_data;
	struct hostif_hdr *hdr;
	hdr = (struct hostif_hdr *)buffer;
	rc = 0;

	DPRINTK(4, "size=%d\n", hdr->size);
	if (hdr->event < HIF_DATA_REQ || HIF_REQ_MAX < hdr->event) {
		DPRINTK(1, "unknown event=%04X\n", hdr->event);
		return 0;
	}

	retval = ks7010_sdio_write(priv, DATA_WINDOW, buffer, size);
	if (retval) {
		DPRINTK(1, " write error : retval=%d\n", retval);
		return -4;
	}

	rw_data = WRITE_STATUS_BUSY;
	retval =
	    ks7010_sdio_write(priv, WRITE_STATUS, &rw_data, sizeof(rw_data));
	if (retval) {
		DPRINTK(1, " error : WRITE_STATUS=%02X\n", rw_data);
		return -3;
	}

	return 0;
}
Пример #3
0
static int ks7010_sdio_update_index(struct ks_wlan_private *priv, u32 index)
{
	int rc = 0;
	int retval;
	unsigned char *data_buf;
	data_buf = NULL;

	data_buf = kmalloc(sizeof(u32), GFP_KERNEL);
	if (!data_buf) {
		rc = 1;
		goto error_out;
	}

	memcpy(data_buf, &index, sizeof(index));
	retval = ks7010_sdio_write(priv, WRITE_INDEX, data_buf, sizeof(index));
	if (retval) {
		rc = 2;
		goto error_out;
	}

	retval = ks7010_sdio_write(priv, READ_INDEX, data_buf, sizeof(index));
	if (retval) {
		rc = 3;
		goto error_out;
	}
 error_out:
	if (data_buf)
		kfree(data_buf);
	return rc;
}
Пример #4
0
/* write data */
static int write_to_device(struct ks_wlan_private *priv, unsigned char *buffer,
			   unsigned long size)
{
	struct hostif_hdr *hdr;
	int ret;

	hdr = (struct hostif_hdr *)buffer;

	DPRINTK(4, "size=%d\n", hdr->size);
	if (le16_to_cpu(hdr->event) < HIF_DATA_REQ ||
	    le16_to_cpu(hdr->event) > HIF_REQ_MAX) {
		DPRINTK(1, "unknown event=%04X\n", hdr->event);
		return 0;
	}

	ret = ks7010_sdio_write(priv, DATA_WINDOW, buffer, size);
	if (ret) {
		DPRINTK(1, " write error : retval=%d\n", ret);
		return ret;
	}

	ret = ks7010_sdio_writeb(priv, WRITE_STATUS, REG_STATUS_BUSY);
	if (ret) {
		DPRINTK(1, " error : WRITE_STATUS\n");
		return ret;
	}

	return 0;
}
Пример #5
0
void ks_wlan_hw_sleep_doze_request(struct ks_wlan_private *priv)
{
	unsigned char rw_data;
	int retval;

	DPRINTK(4, "\n");

	/* clear request */
	atomic_set(&priv->sleepstatus.doze_request, 0);

	if (atomic_read(&priv->sleepstatus.status) == 0) {
		rw_data = GCR_B_DOZE;
		retval =
		    ks7010_sdio_write(priv, GCR_B, &rw_data, sizeof(rw_data));
		if (retval) {
			DPRINTK(1, " error : GCR_B=%02X\n", rw_data);
			goto out;
		}
		DPRINTK(4, "PMG SET!! : GCR_B=%02X\n", rw_data);
		DPRINTK(3, "sleep_mode=SLP_SLEEP\n");
		atomic_set(&priv->sleepstatus.status, 1);
		priv->last_doze = jiffies;
	} else {
		DPRINTK(1, "sleep_mode=%d\n", priv->sleep_mode);
	}

 out:
	priv->sleep_mode = atomic_read(&priv->sleepstatus.status);
	return;
}
Пример #6
0
void ks_wlan_hw_sleep_wakeup_request(struct ks_wlan_private *priv)
{
	unsigned char rw_data;
	int retval;

	DPRINTK(4, "\n");

	/* clear request */
	atomic_set(&priv->sleepstatus.wakeup_request, 0);

	if (atomic_read(&priv->sleepstatus.status) == 1) {
		rw_data = WAKEUP_REQ;
		retval =
		    ks7010_sdio_write(priv, WAKEUP, &rw_data, sizeof(rw_data));
		if (retval) {
			DPRINTK(1, " error : WAKEUP=%02X\n", rw_data);
			goto out;
		}
		DPRINTK(4, "wake up : WAKEUP=%02X\n", rw_data);
		atomic_set(&priv->sleepstatus.status, 0);
		priv->last_wakeup = jiffies;
		++priv->wakeup_count;
	} else {
		DPRINTK(1, "sleep_mode=%d\n", priv->sleep_mode);
	}

 out:
	priv->sleep_mode = atomic_read(&priv->sleepstatus.status);
	return;
}
Пример #7
0
void ks_wlan_hw_wakeup_request(struct ks_wlan_private *priv)
{
	unsigned char rw_data;
	int retval;

	DPRINTK(4, "\n");
	if (atomic_read(&priv->psstatus.status) == PS_SNOOZE) {
		rw_data = WAKEUP_REQ;
		retval =
		    ks7010_sdio_write(priv, WAKEUP, &rw_data, sizeof(rw_data));
		if (retval) {
			DPRINTK(1, " error : WAKEUP=%02X\n", rw_data);
		}
		DPRINTK(4, "wake up : WAKEUP=%02X\n", rw_data);
		priv->last_wakeup = jiffies;
		++priv->wakeup_count;
	} else {
		DPRINTK(1, "psstatus=%d\n",
			atomic_read(&priv->psstatus.status));
	}
}
Пример #8
0
static int ks7010_upload_firmware(struct ks_sdio_card *card)
{
	struct ks_wlan_private *priv = card->priv;
	unsigned int size, offset, n = 0;
	unsigned char *rom_buf;
	unsigned char byte = 0;
	int ret;
	unsigned int length;
	const struct firmware *fw_entry = NULL;

	rom_buf = kmalloc(ROM_BUFF_SIZE, GFP_KERNEL);
	if (!rom_buf)
		return -ENOMEM;

	sdio_claim_host(card->func);

	/* Firmware running ? */
	ret = ks7010_sdio_readb(priv, GCR_A, &byte);
	if (byte == GCR_A_RUN) {
		DPRINTK(0, "MAC firmware running ...\n");
		goto release_host_and_free;
	}

	ret = request_firmware(&fw_entry, ROM_FILE,
			       &priv->ks_sdio_card->func->dev);
	if (ret)
		goto release_host_and_free;

	length = fw_entry->size;

	n = 0;
	do {
		if (length >= ROM_BUFF_SIZE) {
			size = ROM_BUFF_SIZE;
			length = length - ROM_BUFF_SIZE;
		} else {
			size = length;
			length = 0;
		}
		DPRINTK(4, "size = %d\n", size);
		if (size == 0)
			break;
		memcpy(rom_buf, fw_entry->data + n, size);

		offset = n;
		ret = ks7010_sdio_update_index(priv, KS7010_IRAM_ADDRESS + offset);
		if (ret)
			goto release_firmware;

		ret = ks7010_sdio_write(priv, DATA_WINDOW, rom_buf, size);
		if (ret)
			goto release_firmware;

		ret = ks7010_sdio_data_compare(priv, DATA_WINDOW, rom_buf, size);
		if (ret)
			goto release_firmware;

		n += size;

	} while (size);

	ret = ks7010_sdio_writeb(priv, GCR_A, GCR_A_REMAP);
	if (ret)
		goto release_firmware;

	DPRINTK(4, " REMAP Request : GCR_A\n");

	/* Firmware running check */
	for (n = 0; n < 50; ++n) {
		mdelay(10);	/* wait_ms(10); */
		ret = ks7010_sdio_readb(priv, GCR_A, &byte);
		if (ret)
			goto release_firmware;

		if (byte == GCR_A_RUN)
			break;
	}
	DPRINTK(4, "firmware wakeup (%d)!!!!\n", n);
	if ((50) <= n) {
		DPRINTK(1, "firmware can't start\n");
		ret = -EIO;
		goto release_firmware;
	}

	ret = 0;

 release_firmware:
	release_firmware(fw_entry);
 release_host_and_free:
	sdio_release_host(card->func);
	kfree(rom_buf);

	return ret;
}
Пример #9
0
static int ks7010_sdio_probe(struct sdio_func *func,
			     const struct sdio_device_id *device)
{
	struct ks_wlan_private *priv;
	struct ks_sdio_card *card;
	struct net_device *netdev;
	unsigned char rw_data;
	int ret;

	DPRINTK(5, "ks7010_sdio_probe()\n");

	priv = NULL;
	netdev = NULL;

	/* initilize ks_sdio_card */
	card = kzalloc(sizeof(struct ks_sdio_card), GFP_KERNEL);
	if (!card)
		return -ENOMEM;

	card->func = func;
	spin_lock_init(&card->lock);

	/*** Initialize  SDIO ***/
	sdio_claim_host(func);

	/* bus setting  */
	/* Issue config request to override clock rate */

	/* function blocksize set */
	ret = sdio_set_block_size(func, KS7010_IO_BLOCK_SIZE);
	DPRINTK(5, "multi_block=%d sdio_set_block_size()=%d %d\n",
		func->card->cccr.multi_block, func->cur_blksize, ret);

	/* Allocate the slot current */

	/* function enable */
	ret = sdio_enable_func(func);
	DPRINTK(5, "sdio_enable_func() %d\n", ret);
	if (ret)
		goto error_free_card;

	/* interrupt disable */
	sdio_writeb(func, 0, INT_ENABLE, &ret);
	if (ret)
		goto error_free_card;
	sdio_writeb(func, 0xff, INT_PENDING, &ret);
	if (ret)
		goto error_disable_func;

	/* setup interrupt handler */
	ret = sdio_claim_irq(func, ks_sdio_interrupt);
	if (ret)
		goto error_disable_func;

	sdio_release_host(func);

	sdio_set_drvdata(func, card);

	DPRINTK(5, "class = 0x%X, vendor = 0x%X, "
		"device = 0x%X\n", func->class, func->vendor, func->device);

	/* private memory allocate */
	netdev = alloc_etherdev(sizeof(*priv));
	if (netdev == NULL) {
		printk(KERN_ERR "ks7010 : Unable to alloc new net device\n");
		goto error_release_irq;
	}
	if (dev_alloc_name(netdev, "wlan%d") < 0) {
		printk(KERN_ERR "ks7010 :  Couldn't get name!\n");
		goto error_free_netdev;
	}

	priv = netdev_priv(netdev);

	card->priv = priv;
	SET_NETDEV_DEV(netdev, &card->func->dev);	/* for create sysfs symlinks */

	/* private memory initialize */
	priv->ks_wlan_hw.sdio_card = card;
	init_completion(&priv->ks_wlan_hw.ks7010_sdio_wait);
	priv->ks_wlan_hw.read_buf = NULL;
	priv->ks_wlan_hw.read_buf = kmalloc(RX_DATA_SIZE, GFP_KERNEL);
	if (!priv->ks_wlan_hw.read_buf) {
		goto error_free_netdev;
	}
	priv->dev_state = DEVICE_STATE_PREBOOT;
	priv->net_dev = netdev;
	priv->firmware_version[0] = '\0';
	priv->version_size = 0;
	priv->last_doze = jiffies;	/* set current jiffies */
	priv->last_wakeup = jiffies;
	memset(&priv->nstats, 0, sizeof(priv->nstats));
	memset(&priv->wstats, 0, sizeof(priv->wstats));

	/* sleep mode */
	atomic_set(&priv->sleepstatus.doze_request, 0);
	atomic_set(&priv->sleepstatus.wakeup_request, 0);
	atomic_set(&priv->sleepstatus.wakeup_request, 0);

	trx_device_init(priv);
	hostif_init(priv);
	ks_wlan_net_start(netdev);

	ks7010_init_defaults(priv);

	/* Upload firmware */
	ret = ks7010_upload_firmware(priv, card);	/* firmware load */
	if (ret) {
		printk(KERN_ERR
		       "ks7010: firmware load failed !! retern code = %d\n",
		       ret);
		goto error_free_read_buf;
	}

	/* interrupt setting */
	/* clear Interrupt status write (ARMtoSD_InterruptPending FN1:00_0024) */
	rw_data = 0xff;
	sdio_claim_host(func);
	ret = ks7010_sdio_write(priv, INT_PENDING, &rw_data, sizeof(rw_data));
	sdio_release_host(func);
	if (ret) {
		DPRINTK(1, " error : INT_PENDING=%02X\n", rw_data);
	}
	DPRINTK(4, " clear Interrupt : INT_PENDING=%02X\n", rw_data);

	/* enable ks7010sdio interrupt (INT_GCR_B|INT_READ_STATUS|INT_WRITE_STATUS) */
	rw_data = (INT_GCR_B | INT_READ_STATUS | INT_WRITE_STATUS);
	sdio_claim_host(func);
	ret = ks7010_sdio_write(priv, INT_ENABLE, &rw_data, sizeof(rw_data));
	sdio_release_host(func);
	if (ret) {
		DPRINTK(1, " error : INT_ENABLE=%02X\n", rw_data);
	}
	DPRINTK(4, " enable Interrupt : INT_ENABLE=%02X\n", rw_data);
	priv->dev_state = DEVICE_STATE_BOOT;

	priv->ks_wlan_hw.ks7010sdio_wq = create_workqueue("ks7010sdio_wq");
	if (!priv->ks_wlan_hw.ks7010sdio_wq) {
		DPRINTK(1, "create_workqueue failed !!\n");
		goto error_free_read_buf;
	}

	INIT_DELAYED_WORK(&priv->ks_wlan_hw.rw_wq, ks7010_rw_function);
	ks7010_card_init(priv);

	ret = register_netdev(priv->net_dev);
	if (ret)
		goto error_free_read_buf;

	return 0;

 error_free_read_buf:
	kfree(priv->ks_wlan_hw.read_buf);
	priv->ks_wlan_hw.read_buf = NULL;
 error_free_netdev:
	free_netdev(priv->net_dev);
	card->priv = NULL;
 error_release_irq:
	sdio_claim_host(func);
	sdio_release_irq(func);
 error_disable_func:
	sdio_disable_func(func);
 error_free_card:
	sdio_release_host(func);
	sdio_set_drvdata(func, NULL);
	kfree(card);

	return -ENODEV;
}
Пример #10
0
static int ks7010_upload_firmware(struct ks_wlan_private *priv,
				  struct ks_sdio_card *card)
{
	unsigned int size, offset, n = 0;
	unsigned char *rom_buf;
	unsigned char rw_data = 0;
	int retval, rc = 0;
	int length;
	const struct firmware *fw_entry = NULL;

	rom_buf = NULL;

	/* buffer allocate */
	rom_buf = kmalloc(ROM_BUFF_SIZE, GFP_KERNEL);
	if (!rom_buf) {
		rc = 3;
		goto error_out0;
	}

	sdio_claim_host(card->func);

	/* Firmware running ? */
	retval = ks7010_sdio_read(priv, GCR_A, &rw_data, sizeof(rw_data));
	if (rw_data == GCR_A_RUN) {
		DPRINTK(0, "MAC firmware running ...\n");
		rc = 0;
		goto error_out0;
	}

	retval = request_firmware(&fw_entry, ROM_FILE, &priv->ks_wlan_hw.sdio_card->func->dev);
	if (retval)
		return retval;

	length = fw_entry->size;

	/* Load Program */
	n = 0;
	do {
		if (length >= ROM_BUFF_SIZE) {
			size = ROM_BUFF_SIZE;
			length = length - ROM_BUFF_SIZE;
		} else {
			size = length;
			length = 0;
		}
		DPRINTK(4, "size = %d\n", size);
		if (size == 0)
			break;
		memcpy(rom_buf, fw_entry->data + n, size);
		/* Update write index */
		offset = n;
		retval =
		    ks7010_sdio_update_index(priv,
					     KS7010_IRAM_ADDRESS + offset);
		if (retval) {
			rc = 6;
			goto error_out1;
		}

		/* Write data */
		retval = ks7010_sdio_write(priv, DATA_WINDOW, rom_buf, size);
		if (retval) {
			rc = 8;
			goto error_out1;
		}

		/* compare */
		retval =
		    ks7010_sdio_data_compare(priv, DATA_WINDOW, rom_buf, size);
		if (retval) {
			rc = 9;
			goto error_out1;
		}
		n += size;

	} while (size);

	/* Remap request */
	rw_data = GCR_A_REMAP;
	retval = ks7010_sdio_write(priv, GCR_A, &rw_data, sizeof(rw_data));
	if (retval) {
		rc = 11;
		goto error_out1;
	}
	DPRINTK(4, " REMAP Request : GCR_A=%02X\n", rw_data);

	/* Firmware running check */
	for (n = 0; n < 50; ++n) {
		mdelay(10);	/* wait_ms(10); */
		retval =
		    ks7010_sdio_read(priv, GCR_A, &rw_data, sizeof(rw_data));
		if (retval) {
			rc = 11;
			goto error_out1;
		}
		if (rw_data == GCR_A_RUN)
			break;
	}
	DPRINTK(4, "firmware wakeup (%d)!!!!\n", n);
	if ((50) <= n) {
		DPRINTK(1, "firmware can't start\n");
		rc = 12;
		goto error_out1;
	}

	rc = 0;

 error_out1:
	release_firmware(fw_entry);
 error_out0:
	sdio_release_host(card->func);
	if (rom_buf)
		kfree(rom_buf);
	return rc;
}
Пример #11
0
static void ks_sdio_interrupt(struct sdio_func *func)
{
	int retval;
	struct ks_sdio_card *card;
	struct ks_wlan_private *priv;
	unsigned char status, rsize, rw_data;

	card = sdio_get_drvdata(func);
	priv = card->priv;
	DPRINTK(4, "\n");

	if (priv->dev_state >= DEVICE_STATE_BOOT) {
		retval =
		    ks7010_sdio_read(priv, INT_PENDING, &status,
				     sizeof(status));
		if (retval) {
			DPRINTK(1, "read INT_PENDING Failed!!(%d)\n", retval);
			goto intr_out;
		}
		DPRINTK(4, "INT_PENDING=%02X\n", rw_data);

		/* schedule task for interrupt status */
		/* bit7 -> Write General Communication B register */
		/* read (General Communication B register) */
		/* bit5 -> Write Status Idle */
		/* bit2 -> Read Status Busy  */
		if (status & INT_GCR_B
		    || atomic_read(&priv->psstatus.status) == PS_SNOOZE) {
			retval =
			    ks7010_sdio_read(priv, GCR_B, &rw_data,
					     sizeof(rw_data));
			if (retval) {
				DPRINTK(1, " error : GCR_B=%02X\n", rw_data);
				goto intr_out;
			}
			/* DPRINTK(1, "GCR_B=%02X\n", rw_data); */
			if (rw_data == GCR_B_ACTIVE) {
				if (atomic_read(&priv->psstatus.status) ==
				    PS_SNOOZE) {
					atomic_set(&priv->psstatus.status,
						   PS_WAKEUP);
					priv->wakeup_count = 0;
				}
				complete(&priv->psstatus.wakeup_wait);
			}

		}

		do {
			/* read (WriteStatus/ReadDataSize FN1:00_0014) */
			retval =
			    ks7010_sdio_read(priv, WSTATUS_RSIZE, &rw_data,
					     sizeof(rw_data));
			if (retval) {
				DPRINTK(1, " error : WSTATUS_RSIZE=%02X\n",
					rw_data);
				goto intr_out;
			}
			DPRINTK(4, "WSTATUS_RSIZE=%02X\n", rw_data);
			rsize = rw_data & RSIZE_MASK;
			if (rsize) {	/* Read schedule */
				ks_wlan_hw_rx((void *)priv,
					      (uint16_t) (((rsize) << 4)));
			}
			if (rw_data & WSTATUS_MASK) {
#if 0
				if (status & INT_WRITE_STATUS
				    && !cnt_txqbody(priv)) {
					/* dummy write for interrupt clear */
					rw_data = 0;
					retval =
					    ks7010_sdio_write(priv, DATA_WINDOW,
							      &rw_data,
							      sizeof(rw_data));
					if (retval) {
						DPRINTK(1,
							"write DATA_WINDOW Failed!!(%d)\n",
							retval);
					}
					status &= ~INT_WRITE_STATUS;
				} else {
#endif
					if (atomic_read(&priv->psstatus.status) == PS_SNOOZE) {
						if (cnt_txqbody(priv)) {
							ks_wlan_hw_wakeup_request(priv);
							queue_delayed_work
							    (priv->ks_wlan_hw.
							     ks7010sdio_wq,
							     &priv->ks_wlan_hw.
							     rw_wq, 1);
							return;
						}
					} else {
						tx_device_task((void *)priv);
					}
#if 0
				}
#endif
			}
		} while (rsize);
	}

 intr_out:
	queue_delayed_work(priv->ks_wlan_hw.ks7010sdio_wq,
			   &priv->ks_wlan_hw.rw_wq, 0);
	return;
}
Пример #12
0
static void ks_wlan_hw_rx(void *dev, uint16_t size)
{
	struct ks_wlan_private *priv = (struct ks_wlan_private *)dev;
	int retval;
	struct rx_device_buffer *rx_buffer;
	struct hostif_hdr *hdr;
	unsigned char read_status;
	unsigned short event = 0;

	DPRINTK(4, "\n");

	/* receive data */
	if (cnt_rxqbody(priv) >= (RX_DEVICE_BUFF_SIZE - 1)) {
		/* in case of buffer overflow */
		DPRINTK(1, "rx buffer overflow \n");
		goto error_out;
	}
	rx_buffer = &priv->rx_dev.rx_dev_buff[priv->rx_dev.qtail];

	retval =
	    ks7010_sdio_read(priv, DATA_WINDOW, &rx_buffer->data[0],
			     hif_align_size(size));
	if (retval) {
		goto error_out;
	}

	/* length check */
	if (size > 2046 || size == 0) {
#ifdef KS_WLAN_DEBUG
		if (KS_WLAN_DEBUG > 5)
			print_hex_dump_bytes("INVALID DATA dump: ",
					     DUMP_PREFIX_OFFSET,
					     rx_buffer->data, 32);
#endif
		/* rx_status update */
		read_status = READ_STATUS_IDLE;
		retval =
		    ks7010_sdio_write(priv, READ_STATUS, &read_status,
				      sizeof(read_status));
		if (retval) {
			DPRINTK(1, " error : READ_STATUS=%02X\n", read_status);
		}
		goto error_out;
	}

	hdr = (struct hostif_hdr *)&rx_buffer->data[0];
	rx_buffer->size = le16_to_cpu(hdr->size) + sizeof(hdr->size);
	event = hdr->event;
	inc_rxqtail(priv);

	/* read status update */
	read_status = READ_STATUS_IDLE;
	retval =
	    ks7010_sdio_write(priv, READ_STATUS, &read_status,
			      sizeof(read_status));
	if (retval) {
		DPRINTK(1, " error : READ_STATUS=%02X\n", read_status);
	}
	DPRINTK(4, "READ_STATUS=%02X\n", read_status);

	if (atomic_read(&priv->psstatus.confirm_wait)) {
		if (IS_HIF_CONF(event)) {
			DPRINTK(4, "IS_HIF_CONF true !!\n");
			atomic_dec(&priv->psstatus.confirm_wait);
		}
	}

	/* rx_event_task((void *)priv); */
	tasklet_schedule(&priv->ks_wlan_hw.rx_bh_task);

 error_out:
	return;
}
Пример #13
0
int _ks_wlan_hw_power_save(struct ks_wlan_private *priv)
{
	int rc = 0;
	unsigned char rw_data;
	int retval;

	if (priv->reg.powermgt == POWMGT_ACTIVE_MODE)
		return rc;

	if (priv->reg.operation_mode == MODE_INFRASTRUCTURE &&
	    (priv->connect_status & CONNECT_STATUS_MASK) == CONNECT_STATUS) {

		//DPRINTK(1,"psstatus.status=%d\n",atomic_read(&priv->psstatus.status));
		if (priv->dev_state == DEVICE_STATE_SLEEP) {
			switch (atomic_read(&priv->psstatus.status)) {
			case PS_SNOOZE:	/* 4 */
				break;
			default:
				DPRINTK(5, "\npsstatus.status=%d\npsstatus.confirm_wait=%d\npsstatus.snooze_guard=%d\ncnt_txqbody=%d\n",
					atomic_read(&priv->psstatus.status),
					atomic_read(&priv->psstatus.confirm_wait),
					atomic_read(&priv->psstatus.snooze_guard),
					cnt_txqbody(priv));

				if (!atomic_read(&priv->psstatus.confirm_wait)
				    && !atomic_read(&priv->psstatus.snooze_guard)
				    && !cnt_txqbody(priv)) {
					retval =
					    ks7010_sdio_read(priv, INT_PENDING,
							     &rw_data,
							     sizeof(rw_data));
					if (retval) {
						DPRINTK(1,
							" error : INT_PENDING=%02X\n",
							rw_data);
						queue_delayed_work(priv->ks_wlan_hw.ks7010sdio_wq,
								   &priv->ks_wlan_hw.rw_wq, 1);
						break;
					}
					if (!rw_data) {
						rw_data = GCR_B_DOZE;
						retval =
						    ks7010_sdio_write(priv,
								      GCR_B,
								      &rw_data,
								      sizeof(rw_data));
						if (retval) {
							DPRINTK(1,
								" error : GCR_B=%02X\n",
								rw_data);
							queue_delayed_work
							    (priv->ks_wlan_hw.ks7010sdio_wq,
							     &priv->ks_wlan_hw.rw_wq, 1);
							break;
						}
						DPRINTK(4,
							"PMG SET!! : GCR_B=%02X\n",
							rw_data);
						atomic_set(&priv->psstatus.
							   status, PS_SNOOZE);
						DPRINTK(3,
							"psstatus.status=PS_SNOOZE\n");
					} else {
						queue_delayed_work(priv->ks_wlan_hw.ks7010sdio_wq,
								   &priv->ks_wlan_hw.rw_wq, 1);
					}
				} else {
					queue_delayed_work(priv->ks_wlan_hw.
							   ks7010sdio_wq,
							   &priv->ks_wlan_hw.rw_wq,
							   0);
				}
				break;
			}
		}

	}

	return rc;
}