📄 if_gspi.c
字号:
/*
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 + -