⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 if_gspi.c

📁 marvell wifi driver GSPI-8385-LINUX-OMAP1510-5.0.10.p0-144-src.rar
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
	File	: if_gspi.c
*/

#define __WLAN_GSPI__

#include	"if_gspi.h"
#include	"gspi_io.h"

#ifdef		HELPER_IMAGE
#include	"helper.h"
#endif //HELPER_IMAGE

#ifdef GSPI8385
#ifdef THROUGHPUT_TEST
#include	"gspi8385_Thruput.h"
#else
#include	"gspi8385.h"
#endif /* THROUGHPUT_TEST */
#endif /* GSPI8385 */

#ifdef GSPI8399
#include	"gspi8399.h"
#endif /* GSPI8399 */

static int gspi_read_reg32(wlan_private *priv, u16 offset, u32 *data);
static int gspi_read_host_int_status(wlan_private *priv, u8 *data);
static int gspi_read_event_scratch(wlan_private *priv);

void sbi_interrupt(int, void*, struct pt_regs*);
int sbi_prog_firmware(wlan_private *priv);
int sbi_dnld_ready(wlan_private *priv);
int sbi_disable_host_int(wlan_private *priv, u8 mask);
extern int g_dummy_clk_reg;
extern int g_dummy_clk_ioport;

gspi_notifier_rec_t gspi_notifier;

static wlan_private *pwlanpriv;
static wlan_private *(* wlan_add_callback)(void *dev_id);
static int (* wlan_remove_callback)(void *dev_id);

void sbi_interrupt(int irq, void* dev_id, struct pt_regs* fp)
{
	struct net_device       *dev = dev_id;

        ENTER1();

	PRINTK("In the interrupt handler\n");
	PRINTK("#");

        disable_irq(dev->irq);
	wlan_interrupt(dev);

        LEAVE1();
}

static int sbi_add_card(void *card)
{
	if (!wlan_add_callback)
		return -ENODEV;

	pwlanpriv = wlan_add_callback(card);

	if(pwlanpriv)
		return 0;
	else
		return -ENODEV;
}

static int sbi_remove_card(void *card)
{
	if (!wlan_remove_callback)
		return -ENODEV;
		
	pwlanpriv = NULL;
	return wlan_remove_callback(card); 
}

int *sbi_register(wlan_notifier_fn_add add, wlan_notifier_fn_remove remove,
								  void *arg)
{
        int *gspi_ret;

	wlan_add_callback = add;
	wlan_remove_callback = remove;
	
        gspi_notifier.add = (gspi_notifier_fn_p) sbi_add_card;
        gspi_notifier.remove = (gspi_notifier_fn_p) sbi_remove_card;
	gspi_notifier.user_isr = sbi_interrupt;
	gspi_ret = (int *) register_user(&gspi_notifier);

	if(!gspi_ret)
		PRINTK("register_user failed\n");

        return gspi_ret;
}

void sbi_unregister(void)
{
	unregister_user(&gspi_notifier);
}

int sbi_get_cis_info(wlan_private *priv)
{
	ENTER();
	
	LEAVE();
	return WLAN_STATUS_SUCCESS;
}

int sbi_probe_card(void * card_p)
{
	return 0;
}

static int gspi_write_host_int_status(wlan_private *priv, u16 mask)
{
	if(gspi_write_reg(priv->wlan_dev.card, HOST_INT_STATUS_REG, ~mask)) {
		printk("gspi_read_reg failed\n");
		return WLAN_STATUS_FAILURE;
	} 

	return WLAN_STATUS_SUCCESS;
}

#define IPFIELD_ALIGN_OFFSET    2

int sbi_get_int_status(wlan_private *priv , u8 *ireg)
{
        int 		ret = 0;
	u8 		tmp;
	struct sk_buff	*skb;
	u8		*cmdBuf;
	wlan_adapter	*Adapter = priv->adapter;

	sbi_disable_host_int(priv,HIM_DISABLE);
	ret = gspi_read_host_int_status(priv, &tmp);
	enable_irq(priv->wlan_dev.netdev->irq);

	/* re-map bit 0 and bit 1 for WLAN module since the definition is different */
	
	*ireg = tmp & (~(GHIS_TxDnLdRdy | GHIS_RxUpLdRdy));

	if(tmp & GHIS_TxDnLdRdy) {
		priv->wlan_dev.dnld_sent = DNLD_RES_RECEIVED;
		*ireg |= HIS_TxDnLdRdy;
	}

	if(
#ifdef THROUGHPUT_TEST
	(
#endif /* THROUGHPUT_TEST */
	 tmp & GHIS_RxUpLdRdy
#ifdef THROUGHPUT_TEST
	|| !priv->adapter->NumTransfersRx) 
	&& (priv->adapter->ThruputTest & GHIS_RxUpLdRdy)
#endif /* THROUGHPUT_TEST */
	) {
		*ireg |= HIS_RxUpLdRdy;
	}


	PRINTK(KERN_DEBUG ":%02x|", *ireg);
	if(*ireg & HIS_RxUpLdRdy) {

		if(!(skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE))) {
			printk(KERN_ERR "No free skb\n");
			priv->stats.rx_dropped++;
			sbi_enable_host_int(priv,HIM_ENABLE);
			return WLAN_STATUS_FAILURE;
		}

		skb_reserve(skb, IPFIELD_ALIGN_OFFSET);  /*16 Byte Align the IP fields */
		
		/* skb->tail is passed as we are calling skb_put after we
		 * are reading the data */
		if (sbi_card_to_host(priv, MVMS_DAT, 
			&priv->wlan_dev.upld_len,
			skb->data, MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) < 0) {
			printk("ERROR: Data Transfer from device failed\n");
			if (skb)
				kfree_skb(skb);
			sbi_enable_host_int(priv,HIM_ENABLE);
			return WLAN_STATUS_FAILURE;
		}

		skb_put(skb, priv->wlan_dev.upld_len);
		list_add_tail((struct list_head *) skb,
				(struct list_head *) &Adapter->RxSkbQ);
	}

	if(*ireg & HIS_CmdUpLdRdy) {

		if(!Adapter->CurCmd) {
			cmdBuf = priv->wlan_dev.upld_buf;
			Adapter->HisRegCpy &= ~HIS_CmdUpLdRdy;
			*ireg &= ~HIS_CmdUpLdRdy;
		} else {
			cmdBuf = Adapter->CurCmd->BufVirtualAddr;
		}

		if (sbi_card_to_host(priv, MVMS_CMD, 
			&priv->wlan_dev.upld_len,
			cmdBuf, WLAN_UPLD_SIZE) < 0) {
			PRINTK1("ERROR: Data Transfer from device failed\n");
			sbi_enable_host_int(priv,HIM_ENABLE);
			return WLAN_STATUS_FAILURE;
		}
	}
	sbi_enable_host_int(priv,HIM_ENABLE);
	PRINTK("%02x:%02x", *ireg, Adapter->HisRegCpy);

        return ret;
}


int sbi_is_tx_download_ready(wlan_private *priv)
{
        int     rval;
        u8     cs;

        ENTER1();

        if ((rval = gspi_read_host_int_status(priv, &cs)) < 0)
                goto done;

        rval = (cs & HIS_TxDnLdRdy) ? 0 : -EBUSY;
done:
        LEAVE1();
        return rval;
}

int sbi_reenable_host_interrupt(wlan_private *priv, u8 bits)
{
	return WLAN_STATUS_SUCCESS;
}

int sbi_card_init(wlan_private *priv)
{
	io_card_rec_p cardp = priv -> wlan_dev . card;	
	u16	host_int_mask;

	gspi_write_reg(cardp, SPU_BUS_MODE_REG, BUS_MODE_16_NO_DELAY);
	gspi_read_reg(cardp, CHIPREV_REG, &cardp->chiprev);
	printk("Chiprev is %x\n", cardp->chiprev);
	priv->adapter->chip_rev = cardp->chiprev;

	/* Read the HOST_INT_STATUS_REG for ACK the first interrrupt got
	 * from the bootloader. If we don't do this we get a interrupt
	 * as soon as we register the irq. */
	gspi_read_reg(cardp, HOST_INT_STATUS_REG, &host_int_mask);

	cardp->user_arg = (void*) priv->wlan_dev.netdev;
	if(gspi_register_irq(cardp->ctrlr) != GSPI_OK) {
		PRINTK("gspi_register_irq failed\n");
		return WLAN_STATUS_FAILURE;
	}

	priv->wlan_dev.netdev->irq  = cardp->ctrlr->irq;

	return 0;
}

void gspi_reset_autobits(wlan_private* priv)
{
	io_card_rec_p cardp = priv -> wlan_dev . card;
	u16 hicr;

	gspi_read_reg(cardp, HOST_INT_CTRL_REG, &hicr);
	gspi_write_reg(cardp, HOST_INT_CTRL_REG, hicr & ~(HIC_TxDnldAuto|HIC_RxUpldAuto|HIC_CmdDnldAuto|HIC_CmdUpldAuto));
}

int wait_for_hostintstatus(gspi_card_rec_p cardp)
{
#define MAX_WAIT_TRIES 100	
	int i = 0;
	u16 stat;
	
	for( i = 0; i < MAX_WAIT_TRIES; ++i ) {
		gspi_read_reg(cardp, HOST_INT_STATUS_REG, &stat);

		if(stat & GHIS_CmdDnLdRdy)
			return 1;

		udelay(100);
	}

	return WLAN_STATUS_SUCCESS;
}

int sbi_verify_fw_download(wlan_private *priv)
{
	int i;
	u32 scr4;

	for(i = 0; i < MAX_FIRMWARE_POLL_TRIES; ++i) {

		if(gspi_read_reg32(priv, SCRATCH_4_REG, &scr4) < 0) {
			printk("Read from Scratch 4 failed !!!\n");
			return WLAN_STATUS_FAILURE;
		}
	
		if(scr4 == FIRMWARE_DNLD_OK) {
			printk("Firmware download successful !!!\n");
			return WLAN_STATUS_SUCCESS;
		}

		mdelay(100);
	}

	return WLAN_STATUS_FAILURE;
}

#ifdef HELPER_IMAGE
static int sbi_download_wlan_fw_image(wlan_private *priv, const u8 *firmware, int firmwarelen)
{
	int     ret;
	u16      dlimage[1024];
	u16	len;
	u32     cnt=0;
	gspi_card_rec_p cardp = priv -> wlan_dev . card;

	ENTER();

	printk("WLAN_FW: Downloading firmware of size %d bytes\n", firmwarelen);

	/* Wait initially for the first non-zero value */

	do {
		udelay(100);
		gspi_read_reg(cardp, SCRATCH_1_REG, &len);
	} while(!len);
		
	for(;;) {
        	if(!wait_for_hostintstatus(cardp)) {
       			printk("Firmware download died ......\n");
			return WLAN_STATUS_FAILURE;
        	}

		gspi_read_reg(cardp, SCRATCH_1_REG, &len);

		if(!len) {
			printk("\nFirmware download complete \n");
			break;
		}

		if(len & 1) {
			printk("CRC Error\n");
			len &= ~1;
		} else {
			printk(".");
		}

		memcpy(dlimage, firmware + cnt, len);
		gspi_write_data_direct(cardp, (u8 *) dlimage, CMD_RDWRPORT_REG, (len/2)+1);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -