📄 if_gspi.c
字号:
gspi_write_reg(cardp, HOST_INT_STATUS_REG, 0x0000);
gspi_write_reg(cardp, CARD_INT_CAUSE_REG, CIC_CmdDnLdOvr);
cnt += len;
}
printk("Firmware Image of Size %d bytes downloaded, cnt %d\n", firmwarelen, cnt);
ret = WLAN_STATUS_SUCCESS;
LEAVE();
return ret;
}
int sbi_download_wlan_fw(wlan_private *priv)
{
return sbi_download_wlan_fw_image(priv,fmimage,sizeof(fmimage));
}
#endif
/**
* This function is used for transferring firmware from the host to the
* client.
*/
int sbi_prog_firmware_image(wlan_private *priv, const u8 *firmware, int firmwarelen)
{
int ret = WLAN_STATUS_SUCCESS;
u16 dlimage[FIRMWARE_DNLD_PCKCNT];
int fwblknow;
gspi_card_rec_p cardp = priv -> wlan_dev . card;
for(fwblknow = 0;fwblknow < firmwarelen;fwblknow += FIRMWARE_DNLD_PCKCNT) {
gspi_write_reg(cardp, SCRATCH_1_REG, FIRMWARE_DNLD_PCKCNT);
if(!wait_for_hostintstatus(cardp)) {
printk("Firmware download died ......\n");
return WLAN_STATUS_FAILURE;
}
memcpy(dlimage, firmware + fwblknow, FIRMWARE_DNLD_PCKCNT);
gspi_write_data_direct(cardp, (u8 *) dlimage,CMD_RDWRPORT_REG,
(FIRMWARE_DNLD_PCKCNT/2)+1);
gspi_write_reg(cardp, HOST_INT_STATUS_REG, 0x0000);
gspi_write_reg(cardp, CARD_INT_CAUSE_REG, CIC_CmdDnLdOvr);
printk(".");
}
printk("\nDownload %d bytes of firmware\n",firmwarelen);
/* Writing 0 to Scr1 is to indicate the end of Firmware dwld */
gspi_write_reg(cardp, SCRATCH_1_REG, FIRMWARE_DNLD_END);
gspi_write_reg(cardp, HOST_INT_STATUS_REG, 0x0000);
gspi_write_reg(cardp, CARD_INT_CAUSE_REG, CIC_CmdDnLdOvr);
ret = WLAN_STATUS_SUCCESS;
LEAVE();
return ret;
}
int sbi_prog_firmware(wlan_private *priv)
{
return sbi_prog_firmware_image(priv, fmimage, sizeof(fmimage));
}
#ifdef HELPER_IMAGE
int sbi_prog_helper(wlan_private *priv)
{
return sbi_prog_firmware_image(priv, helperimage, sizeof(helperimage));
}
#endif
int sbi_register_dev(wlan_private *priv)
{
int ret = WLAN_STATUS_SUCCESS;
ENTER();
/* Initialize the private structure */
strncpy(priv->wlan_dev.name, "gspi0", sizeof(priv->wlan_dev.name));
priv->wlan_dev.ioport = 0;
priv->wlan_dev.upld_rcv = 0;
priv->wlan_dev.upld_typ = 0;
priv->wlan_dev.upld_len = 0;
sbi_card_init(priv);
LEAVE();
return ret;
}
int sbi_unregister_dev(wlan_private *priv)
{
io_card_rec_p cardp = priv -> wlan_dev . card;
ENTER();
/* Disable interrupts on the card */
sbi_disable_host_int(priv, 0xff);
gspi_unregister_irq(cardp->ctrlr);
PRINTK("Sending reset ........\n");
gspi_reset();
LEAVE();
return WLAN_STATUS_SUCCESS;
}
/**
* Enable host interrupt.
*/
int sbi_enable_host_int(wlan_private *priv, u8 mask)
{
int ret=WLAN_STATUS_SUCCESS;
ENTER();
/* Enabling TxDnldRdy, RxDnldRdy, CmdUpldRdy, CmdDnldRdy, CardEvent
* interrupts */
gspi_write_reg(priv->wlan_dev.card, HOST_INT_STATUS_MASK_REG,
HISM_TxDnLdRdy | HISM_RxUpLdRdy | HISM_CmdDnLdRdy
| HISM_CardEvent | HISM_CmdUpLdRdy);
gspi_reset_autobits(priv);
LEAVE();
return ret;
}
/**
* Disable host interrupt.
*/
int sbi_disable_host_int(wlan_private *priv, u8 mask)
{
int ret = WLAN_STATUS_SUCCESS;
gspi_card_rec_p cardp = priv -> wlan_dev . card;
ENTER();
ret = gspi_write_reg(cardp, HOST_INT_STATUS_MASK_REG, 0x00);
if (ret < 0)
goto done;
done:
LEAVE();
return ret;
}
int gspi_read_reg32(wlan_private *priv, u16 reg, u32 *data)
{
u16 readdt[3];
gspi_card_rec_p cardp = priv -> wlan_dev . card;
if(gspi_read_data_direct(cardp, (u8 *) readdt, reg, 4) < 0) {
printk("Error on gspi_read_reg32(%02x)\n", reg);
return WLAN_STATUS_FAILURE;
}
memcpy(data, readdt, 4);
return WLAN_STATUS_SUCCESS;
}
int gspi_read_host_int_status(wlan_private *priv, u8 *curHIS)
{
int ret;
u16 his;
gspi_card_rec_p cardp = priv -> wlan_dev . card;
if (!(ret = gspi_read_reg(cardp, HOST_INT_STATUS_REG, &his)))
*curHIS = (u8) his;
return ret;
}
/**
* This function is used for sending data to the GSPI card.
*/
int sbi_host_to_card(wlan_private *priv, u8 type, u8 *payload, u16 nb)
{
int ret = WLAN_STATUS_SUCCESS;
u16 writeReg;
u8 intType;
gspi_card_rec_p cardp = priv->wlan_dev.card;
ENTER();
intType = type ? CIC_CmdDnLdOvr : CIC_TxDnLdOvr;
writeReg = (type) ? CMD_RDWRPORT_REG : DATA_RDWRPORT_REG;
priv->wlan_dev.dnld_sent = (type) ? DNLD_CMD_SENT : DNLD_DATA_SENT;
if (nb & 0x0001)
nb += 1;
/* If the bytes written is not a multiple of four then make it
a multiple of four as the RWPORT is 4 byte aligned from
the host */
if (!(nb % 4))
ret = gspi_write_data_direct(cardp, payload, writeReg, (nb/2)+1);
else
ret = gspi_write_data_direct(cardp, payload, writeReg, (nb/2)+2);
gspi_write_reg(cardp, CARD_INT_CAUSE_REG, intType);
#ifdef TX_PRINT_DEBUG
PRINTK("+");
printk("NB = %d\n", nb);
gspi_hexdump8("Write", payload, nb);
#endif
LEAVE();
return ret;
}
/**
* This function is used to read data from the card.
* Type specifies from which port data is to be read
* Size of data read will be given to caller in nb
*/
int sbi_card_to_host(wlan_private *priv, u32 type,
u32 *nb, u8 *payload, u16 npayload)
{
int ret = WLAN_STATUS_SUCCESS;
u16 len;
u16 intType=0, readReg;
gspi_card_rec_p cardp = priv->wlan_dev.card;
ENTER();
intType = type ? CIC_CmdUpLdOvr : CIC_RxUpLdOvr;
readReg = type ? CMD_RDWRPORT_REG : DATA_RDWRPORT_REG;
gspi_read_reg(cardp, (type) ? SCRATCH_2_REG : SCRATCH_1_REG, &len);
if (!len || len > npayload) {
printk(KERN_DEBUG "Error packet of len %d\n", len);
len = MRVDRV_ETH_RX_PACKET_BUFFER_SIZE;
}
if (len & 0x0001)
len += 1;
if (!(len % 4))
ret = gspi_read_data_direct(cardp, payload, readReg, (len/2)+1);
else
ret = gspi_read_data_direct(cardp, payload, readReg, (len/2)+2);
gspi_write_reg(cardp, CARD_INT_CAUSE_REG, intType);
*nb = len;
#ifdef RX_PRINT_DEBUG
printk("Receiving packet of len %d\n", len);
gspi_hexdump8("Read", payload, len);
printk("-");
#endif
LEAVE();
return ret;
}
int sbi_read_event_cause(wlan_private *priv)
{
u16 intType;
intType = CIC_HostEvent;
gspi_read_event_scratch(priv);
/* re-enable the interrupt */
gspi_write_host_int_status(priv, intType);
return WLAN_STATUS_SUCCESS;
}
/**
* Read from the event scratch register
*/
int gspi_read_event_scratch(wlan_private *priv)
{
int ret;
ENTER();
ret = gspi_read_reg32(priv, SCRATCH_3_REG, &priv->adapter->EventCause);
if (ret < 0) {
PRINTK("ERROR: Event Scratch Pad Register Read!\n");
return ret;
}
PRINTK("The event is %x\n", priv->adapter->EventCause);
priv->adapter->EventCause <<= 3;
LEAVE();
return WLAN_STATUS_SUCCESS;
}
#ifdef DEEP_SLEEP
inline int sbi_exit_deep_sleep(wlan_private *priv)
{
io_card_rec_p card = priv->wlan_dev.card;
u16 hicr;
int ret;
ret = gspi_read_reg(card, HOST_INT_CTRL_REG, &hicr);
if(!ret)
ret = gspi_write_reg(card, HOST_INT_CTRL_REG, hicr | HIC_WakeUp); //Set WakeUp
return ret;
}
int sbi_reset_deepsleep_wakeup(wlan_private *priv)
{
io_card_rec_p card = priv->wlan_dev.card;
u16 hicr;
int ret;
ret = gspi_read_reg(card, HOST_INT_CTRL_REG, &hicr);
if(!ret)
ret = gspi_write_reg(card, HOST_INT_CTRL_REG, hicr & ~HIC_WakeUp); //Reset WakeUp
return ret;
}
#endif // DEEP_SLEEP
#ifdef CONFIG_PM
inline int sbi_suspend(wlan_private * priv)
{
ENTER();
LEAVE();
return WLAN_STATUS_SUCCESS;
}
inline int sbi_resume(wlan_private * priv)
{
ENTER();
LEAVE();
return WLAN_STATUS_SUCCESS;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -