📄 if_cf.c
字号:
if (bits & HIS_CardEvent)
tmp |= CF_CCR_CS_CardEvent;
if (bits & HIS_CmdUpLdRdy)
tmp |= CF_CCR_CS_CmdRspRdy;
sbi_enable_host_int(priv, tmp);
return 0;
}
int sbi_disable_host_int(wlan_private * priv, u8 int_mask)
{
cfreg *reg = (cfreg *)priv->wlan_dev.ioport;
u16 mask = (u16) int_mask;
ENTER();
if (!mask)
mask = CF_HCR_HIM_MASK;
mask &= CF_HCR_HIM_MASK; // check if this is rqrd?
cardp.host_int_mask |= mask;
PRINTK("host in mask in init = 0x%X\n", cardp.host_int_mask);
outw(cardp.host_int_mask, reg->host.int_mask);
// For debugging.
mask = inw(reg->host.int_mask);
LEAVE();
return 0;
}
int sbi_enable_host_int(wlan_private * priv, u8 int_mask)
{
cfreg *reg = (cfreg *)priv->wlan_dev.ioport;
u16 mask = int_mask;
ENTER();
if (!mask)
mask = CF_HCR_HIM_MASK;
mask &= CF_HCR_HIM_MASK;
PRINTK("mask bit = 0x%X\n", mask);
PRINTK("before masking host_int_mask = 0x%X\n", cardp.host_int_mask);
cardp.host_int_mask &= ~mask;
PRINTK("host_int_mask=0x%x\n", cardp.host_int_mask);
outw(cardp.host_int_mask, reg->host.int_mask);
LEAVE();
return 0;
}
int sbi_unregister_dev(wlan_private * priv)
{
ENTER();
kfree((void *)priv->wlan_dev.ioport);
free_irq(priv->wlan_dev.netdev->irq, priv->wlan_dev.netdev);
LEAVE();
return 0;
}
int sbi_register_dev(wlan_private * priv)
{
int ret;
ENTER();
strncpy(priv->wlan_dev.name, cfio_dev_info, sizeof(priv->wlan_dev.name));
priv->wlan_dev.ioport = (u32)kmalloc(sizeof(cfreg), GFP_KERNEL);
priv->wlan_dev.upld_rcv = 0;
priv->wlan_dev.upld_typ = 0;
priv->wlan_dev.upld_len = 0;
cardp.eth_dev = priv->wlan_dev.netdev;
printk(KERN_DEBUG "IRQ %d\n", cardp.irq);
ret =
request_irq(
cardp.irq,
cf_interrupt,
SA_SHIRQ,
"cf_irq",
priv->wlan_dev.netdev
);
if (ret != 0)
{
PRINTK("Call to request_irq failed\n");
priv->wlan_dev.card = NULL;
LEAVE();
return ret;
}
priv->wlan_dev.card = (void *)&cardp;
priv->wlan_dev.netdev->irq = cardp.irq;
priv->wlan_dev.netdev->base_addr = cardp.port;
priv->adapter->irq = cardp.irq;
init_cf_addr(priv);
LEAVE();
return 0; /* success */
}
int sbi_host_to_card(wlan_private *priv, u8 type, u8 *buf, u16 len)
{
int ret = -1;
ENTER();
if (type == MVMS_DAT)
{
priv->wlan_dev.dnld_sent = DNLD_DATA_SENT;
ret = cf_tx_block(priv, buf, (u16)len);
}
else if (type == MVMS_CMD)
{
ret = cf_send_cmd(priv, (u16 *)buf, len);
}
else
{
ret = WLAN_STATUS_FAILURE;
}
LEAVE();
return ret;
}
int sbi_get_cis_info(wlan_private *priv)
{
wlan_adapter *Adapter = priv->adapter;
client_handle_t handle = cisinfo.handle;
tuple_t tuple;
char buf[64], cisbuf[512];
int ofs=0, count=6;
ENTER();
memset(cisbuf, 0x0, sizeof(cisbuf));
tuple.Attributes = 0;
tuple.TupleData = buf;
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
CIS(CISTPL_CONFIG);
CIS(CISTPL_CFTABLE_ENTRY);
CIS(CISTPL_MANFID);
CIS(CISTPL_FUNCID);
CIS(CISTPL_FUNCE);
do
{
if (CardServices(GetNextTuple, handle, &tuple))
goto error;
if (CardServices(GetTupleData, handle, &tuple))
goto error;
cisbuf[ofs++] = tuple.TupleCode;
cisbuf[ofs++] = tuple.TupleLink;
memcpy(cisbuf+ofs, tuple.TupleData, tuple.TupleLink);
ofs += tuple.TupleLink;
} while (count--);
CIS(CISTPL_VERS_1);
CIS(CISTPL_DEVICE_A);
CIS(CISTPL_DEVICE);
memset(Adapter->CisInfoBuf, 0x0, sizeof(Adapter->CisInfoBuf));
memcpy(Adapter->CisInfoBuf, cisbuf, ofs);
Adapter->CisInfoLen = ofs;
error:
PRINTK("card configuration failed...\n");
LEAVE();
return 0;
}
int sbi_probe_card(void *card_p)
{
ENTER();
/*
* Here we simply return zero since we are already done with this
* operation in the cf_config() function
*/
LEAVE();
return 0;
}
int sbi_verify_fw_download(wlan_private * priv)
{
cfreg *reg = (cfreg *)priv->wlan_dev.ioport;
u8 rev = inb(reg->card.product_id);
priv->adapter->chip_rev = rev;
PRINTK("chip rev is: %02x\n", rev);
cardp.do_read_modify_write = 0;
cardp.do_get_int_work_around = 0;
#if defined (CF8305)
cardp.do_read_modify_write = 1;
cardp.do_get_int_work_around = 1;
#elif defined (CF8381)
if (rev < 0x04)
{
PRINTK("sbi_register_dev: cf8381 older than rev. B3.\n");
PRINTK("sbi_register_dev: do r-m-w and intr w-around.\n");
cardp.do_read_modify_write = 1;
cardp.do_get_int_work_around = 1;
}
#elif defined (CF8385)
if (rev < 0x12)
{
PRINTK("sbi_register_dev: cf8385 older than rev. B1.\n");
PRINTK("sbi_register_dev: do r-m-w and intr w-around.\n");
cardp.do_read_modify_write = 1;
cardp.do_get_int_work_around = 0;
}
#endif
return 0;
}
int sbi_prog_firmware(wlan_private * priv)
{
cfreg *reg = (cfreg *)priv->wlan_dev.ioport;
u32 size_total;
u32 size_sent;
u32 size_block;
u8 buf[256];
u8 temp;
int r;
temp = inb(reg->card.scratch);
if (temp == CF_SCRATCH_FIRMWARE_READY)
return 0;
if (temp != CF_SCRATCH_HOST_BOOT_WAITING)
return -1;
size_total = sizeof(init_image);
size_sent = 0;
size_block = FW_BLOCK_SIZE;
while (size_sent < size_total)
{
PRINTK(" loading %06d of %06d bytes\n", size_sent, size_total);
if (size_total - size_sent < size_block)
size_block = (size_total - size_sent);
memcpy(buf, &init_image[size_sent], size_block);
outw(FW_BLOCK_SIZE, reg->host.io_cmd_write_len);
outsw(reg->host.io_cmd_write, buf, FW_BLOCK_SIZE / 2);
outb(CF_HCR_HS_CmdDnLdOvr, reg->host.status);
wmb();
outw(CF_HCR_CIC_CmdDnLdOvr, reg->host.int_cause);
r =
poll_reg(
reg->card.status,
CF_CCR_CS_CmdDnLdRdy,
FW_RETRY,
10
);
if (r != 0)
return -1;
size_sent += size_block;
}
outw(0x00, reg->host.io_cmd_write_len);
outb(CF_HCR_HS_CmdDnLdOvr, reg->host.status);
wmb();
outw(CF_HCR_CIC_CmdDnLdOvr, reg->host.int_cause);
return 0;
}
#ifdef HELPER_IMAGE
int sbi_prog_helper(wlan_private * priv)
{
return sbi_prog_firmware(priv);
}
#endif
#ifdef HELPER_IMAGE
int sbi_download_wlan_fw(wlan_private * priv)
{
cfreg *reg = (cfreg *)priv->wlan_dev.ioport;
u16 len;
int i;
int r;
int retry;
r = poll_reg(reg->card.sq_raddr0, 0x0010, HP_RETRY, 1000);
if (r < 0)
return -1;
retry = 0;
for (i = 0; i < sizeof(fmimage); i += len)
{
len = inw(reg->card.sq_raddr0);
retry = (len & 0x0001) ? retry + 1: 0;
if (retry > 20)
return -1;
if (retry > 0)
i -= len;
PRINTK(" loading %06d of %06d bytes\n", i, sizeof(fmimage));
outw(len + 1, reg->host.io_cmd_write_len);
outsw(reg->host.io_cmd_write, &fmimage[i], len / 2);
outb(CF_HCR_HS_CmdDnLdOvr, reg->host.status);
outw(CF_HCR_CIC_CmdDnLdOvr, reg->host.int_cause);
r =
poll_reg(
reg->card.status,
CF_CCR_CS_CmdDnLdRdy,
FW_RETRY,
0
);
if (r < 0)
{
PRINTK(" failed %06d bytes\n", i);
return -1;
}
}
r = poll_reg(reg->card.scratch, CF_SCRATCH_FIRMWARE_READY, FW_RETRY, 50);
if (r < 0)
{
PRINTK(" firmware failed!\n");
return -1;
}
PRINTK(" firmware started!\n");
return 0;
}
#endif // HELPER_IMAGE
#ifdef DEEP_SLEEP
inline int sbi_enter_deep_sleep(wlan_private * priv)
{
ENTER();
LEAVE();
return 0;
}
inline int sbi_exit_deep_sleep(wlan_private* priv)
{
cfreg *reg = (cfreg *)priv->wlan_dev.ioport;
outb(CF_SCRATCH_DEEPSLEEP_EXIT, reg->card.scratch);
cfio_read_cfg_reg(priv);
return 0;
}
inline int sbi_reset_deepsleep_wakeup(wlan_private * priv)
{
ENTER();
LEAVE();
return 0;
}
#endif // DEEP_SLEEP
int sbi_read_ioreg(wlan_private *priv, u8 func, u32 reg, u8 *dat)
{
/* TODO Remove this after correcting errors in WLAN layer
* This function is dummy for CF this is defined only
* to resolve undefined symbol errors while loading the
* module
*/
return 1;
}
int sbi_write_ioreg(wlan_private * priv, u8 func, u32 reg, u8 dat)
{
/* TODO Remove this after correcting errors in WLAN layer
* This function is dummy for CF this is defined only
* to resolve undefined symbol errors while loading the
* module
*/
return 1;
}
int sbi_read_cfreg(wlan_private * priv, int offset)
{
u16 usval;
ENTER();
usval = inw(priv->wlan_dev.netdev->base_addr + offset);
LEAVE();
return usval;
}
int sbi_write_cfreg(wlan_private * priv, int offset, u16 value)
{
ENTER();
outw(value, priv->wlan_dev.netdev->base_addr + offset);
LEAVE();
return 0;
}
void sbi_trigger_rx(wlan_private * priv)
{
ENTER();
if (priv->adapter->CurrentTxSkb)
priv->adapter->HisRegCpy |= HIS_TxDnLdRdy;
else
cf_KickstartRX(priv);
LEAVE();
}
#ifdef CONFIG_MARVELL_PM
int sbi_suspend(wlan_private * priv)
{
ENTER();
LEAVE();
return 0;
}
int sbi_resume(wlan_private * priv)
{
ENTER();
LEAVE();
return 0;
}
#endif
/* End of file */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -