Exemple #1
0
static int wlan_xmit(struct sk_buff *skb, struct net_device *dev)
{
	wlan_vif_t *vif;
	tx_msg_t msg = { 0 };
	msg_q_t *msg_q;
	int ret, addr_len = 0;
	struct sk_buff *wapi_skb;

	vif = ndev_to_vif(dev);
	msg_q = wlan_tcpack_q(vif, skb->data, skb->len);

	if (vif->cfg80211.cipher_type == WAPI
	    && vif->cfg80211.connect_status == ITM_CONNECTED
	    && vif->cfg80211.key_len[PAIRWISE][vif->cfg80211.
					       key_index[PAIRWISE]] != 0
	    && (*(u16 *) ((u8 *) skb->data + ETH_PKT_TYPE_OFFSET) != 0xb488)) {
		wapi_skb = dev_alloc_skb(skb->len + 100 + NET_IP_ALIGN);
		skb_reserve(wapi_skb, NET_IP_ALIGN);
		memcpy(wapi_skb->data, skb->data, ETHERNET_HDR_LEN);
		addr_len =
		    wlan_tx_wapi_encryption(vif, skb->data,
					    (skb->len - ETHERNET_HDR_LEN),
					    ((unsigned char *)(wapi_skb->data) +
					     ETHERNET_HDR_LEN));
		addr_len = addr_len + ETHERNET_HDR_LEN;
		skb_put(wapi_skb, addr_len);
		dev_kfree_skb(skb);
		skb = wapi_skb;
	}

	msg.p = (void *)skb;
	msg.slice[0].data = skb->data;
	msg.slice[0].len = skb->len;
	msg.hdr.mode = vif->id;
	msg.hdr.type = HOST_SC2331_PKT;
	msg.hdr.subtype = 0;
	msg.hdr.len = skb->len;

	ret = msg_q_in(msg_q, &msg);
	if (OK != ret) {
		printkd("L-PKT\n");
		dev_kfree_skb(skb);
		return NETDEV_TX_OK;
	}
	vif->ndev->stats.tx_bytes += skb->len;
	vif->ndev->stats.tx_packets++;
	dev->trans_start = jiffies;
	g_wlan.wlan_core.need_tx++;
	core_up();
	return NETDEV_TX_OK;
}
Exemple #2
0
/*Transmit interface*/
static int sprdwl_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
	struct sprdwl_priv *priv = netdev_priv(dev);
	struct sblock blk;
	int ret;
	u8 *addr = NULL;

#ifdef CONFIG_SPRDWL_FW_ZEROCOPY
	if (priv->tx_free < TX_FLOW_LOW) {
		dev_err(&dev->dev, "tx flow control full\n");
		netif_stop_queue(dev);
		priv->ndev->stats.tx_fifo_errors++;
		return NETDEV_TX_BUSY;
	}
#endif
	/*Get a free sblock.*/
	ret = sblock_get(WLAN_CP_ID, WLAN_SBLOCK_CH, &blk, 0);
	if (ret) {
		dev_err(&dev->dev, "Failed to get free sblock (%d)!\n", ret);
		netif_stop_queue(dev);
		priv->ndev->stats.tx_fifo_errors++;
		return NETDEV_TX_BUSY;
	}

	if (blk.length < skb->len) {
		dev_err(&dev->dev, "The size of sblock is so tiny!\n");
		priv->ndev->stats.tx_fifo_errors++;
		sblock_put(WLAN_CP_ID, WLAN_SBLOCK_CH, &blk);
		dev_kfree_skb_any(skb);
		priv->txrcnt = 0;
		return NETDEV_TX_OK;
	}

#ifdef CONFIG_SPRDWL_FW_ZEROCOPY
	addr = blk.addr + SIPC_TRANS_OFFSET;
#else
	addr = blk.addr;
#endif
	priv->tx_free--;
	if (priv->connect_status == SPRDWL_CONNECTED &&
	    priv->cipher_type == SPRDWL_CIPHER_WAPI &&
/*            priv->key_len[GROUP][priv->key_index[GROUP]] != 0 &&*/
	    priv->key_len[PAIRWISE][priv->key_index[PAIRWISE]] != 0 &&
	    (*(u16 *)((u8 *)skb->data + ETH_PKT_TYPE_OFFSET) != 0xb488)) {
		memcpy(((u8 *)addr), skb->data, ETHERNET_HDR_LEN);
		blk.length = wlan_tx_wapi_encryption(priv,
					skb->data,
					(skb->len - ETHERNET_HDR_LEN),
					((u8 *)addr + ETHERNET_HDR_LEN))
					+ ETHERNET_HDR_LEN;
	} else {
		blk.length = skb->len;
		memcpy(((u8 *)addr), skb->data, skb->len);
	}

#ifdef DUMP_TRANSMIT_PACKET
	print_hex_dump(KERN_DEBUG, "transmit packet: ", DUMP_PREFIX_OFFSET,
		       16, 1, skb->data, skb->len, 0);
#endif
	ret = sblock_send(WLAN_CP_ID, WLAN_SBLOCK_CH, &blk);
	if (ret) {
		dev_err(&dev->dev, "Failed to send sblock (%d)!\n", ret);
		sblock_put(WLAN_CP_ID, WLAN_SBLOCK_CH, &blk);
		priv->tx_free++;
		priv->ndev->stats.tx_fifo_errors++;
		if (priv->txrcnt > SETH_RESEND_MAX_NUM)
			netif_stop_queue(dev);
		priv->txrcnt++;
		return NETDEV_TX_BUSY;
	}

	/*Statistics*/
	priv->ndev->stats.tx_bytes += skb->len;
	priv->ndev->stats.tx_packets++;
	dev->trans_start = jiffies;
	priv->txrcnt = 0;

	dev_kfree_skb_any(skb);

	return NETDEV_TX_OK;
}