static struct sk_buff *if_cs_receive_data(struct lbs_private *priv) { struct sk_buff *skb = NULL; u16 len; u8 *data; lbs_deb_enter(LBS_DEB_CS); len = if_cs_read16(priv->card, IF_CS_READ_LEN); if (len == 0 || len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) { lbs_pr_err("card data buffer has invalid # of bytes (%d)\n", len); priv->dev->stats.rx_dropped++; goto dat_err; } skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE + 2); if (!skb) goto out; skb_put(skb, len); skb_reserve(skb, 2);/* 16 byte align */ data = skb->data; /* read even number of bytes, then odd byte if necessary */ if_cs_read16_rep(priv->card, IF_CS_READ, data, len/sizeof(u16)); if (len & 1) data[len-1] = if_cs_read8(priv->card, IF_CS_READ); dat_err: if_cs_write16(priv->card, IF_CS_HOST_STATUS, IF_CS_BIT_RX); if_cs_write16(priv->card, IF_CS_HOST_INT_CAUSE, IF_CS_BIT_RX); out: lbs_deb_leave_args(LBS_DEB_CS, "ret %p", skb); return skb; }
/* * Get the command result out of the card. */ static int if_cs_receive_cmdres(struct lbs_private *priv, u8 *data, u32 *len) { unsigned long flags; int ret = -1; u16 status; lbs_deb_enter(LBS_DEB_CS); /* is hardware ready? */ status = if_cs_read16(priv->card, IF_CS_CARD_STATUS); if ((status & IF_CS_BIT_RESP) == 0) { netdev_err(priv->dev, "no cmd response in card\n"); *len = 0; goto out; } *len = if_cs_read16(priv->card, IF_CS_RESP_LEN); if ((*len == 0) || (*len > LBS_CMD_BUFFER_SIZE)) { netdev_err(priv->dev, "card cmd buffer has invalid # of bytes (%d)\n", *len); goto out; } /* read even number of bytes, then odd byte if necessary */ if_cs_read16_rep(priv->card, IF_CS_RESP, data, *len/sizeof(u16)); if (*len & 1) data[*len-1] = if_cs_read8(priv->card, IF_CS_RESP); /* This is a workaround for a firmware that reports too much * bytes */ *len -= 8; ret = 0; /* Clear this flag again */ spin_lock_irqsave(&priv->driver_lock, flags); priv->dnld_sent = DNLD_RES_RECEIVED; spin_unlock_irqrestore(&priv->driver_lock, flags); out: lbs_deb_leave_args(LBS_DEB_CS, "ret %d, len %d", ret, *len); return ret; }