Пример #1
0
static int saudio_wait_common_cmd(uint32_t dst, uint32_t channel,
				      uint32_t cmd, uint32_t subcmd,int32_t timeout)
{
	int result = 0;
	struct sblock blk = { 0 };
	struct cmd_common *common = NULL;
	ADEBUG();
	result =
	    sblock_receive(dst, channel, (struct sblock *)&blk, timeout);
	if (result < 0) {
		ETRACE("sblock_receive dst %d, channel %d result is %d \n", dst,
		       channel, result);
		return result;
	}

	common = (struct cmd_common *)blk.addr;
	pr_debug("dst is %d, channel %d, common->command is %x ,sub cmd %x,\n",
		 dst, channel, common->command, common->sub_cmd);
	if (subcmd) {
		if ((common->command == cmd) && (common->sub_cmd == subcmd)) {
			result = 0;
		} else {
			result = -1;
		}
	} else {
		if (common->command == cmd) {
			result = 0;
		} else {
			result = -1;
		}
	}
	sblock_release(dst, channel, &blk);
	return result;
}
Пример #2
0
static int saudio_clear_cmd(uint32_t dst, uint32_t channel)
{
	int result = 0;
	int i = 0;
	struct sblock blk = { 0 };
	do {
		result = sblock_receive(dst, channel,  (struct sblock *)&blk, 0);
		if (!result) {
			sblock_release(dst, channel, &blk);
		}
	} while (!result);
	return result;
}
Пример #3
0
static int saudio_clear_ctrl_cmd(struct snd_saudio *saudio)
{
	int result = 0;
	int i = 0;
	struct sblock blk = { 0 };
	struct saudio_dev_ctrl *dev_ctrl = NULL;

	for (i = 0; i < SAUDIO_DEV_MAX; i++) {	
		dev_ctrl = &saudio->dev_ctrl[i];
		do {
			result =
			    sblock_receive(dev_ctrl->dst, dev_ctrl->channel,
					   (struct sblock *)&blk, 0);
			if (!result) {
				sblock_release(dev_ctrl->dst, dev_ctrl->channel,
					       &blk);
			}
		} while (!result);
	}

	return result;
}
Пример #4
0
static int sprdwl_rx_handler(struct napi_struct *napi, int budget)
{
	struct sprdwl_priv *priv = container_of(napi, struct sprdwl_priv, napi);
	struct sblock blk;
	struct sk_buff *skb;
	int ret, work_done;
	u16 decryp_data_len = 0;
	struct wlan_sblock_recv_data *data;
	uint32_t length = 0;
#ifdef CONFIG_SPRDWL_FW_ZEROCOPY
	u8 offset = 0;
#endif
	for (work_done = 0; work_done < budget; work_done++) {
		ret = sblock_receive(WLAN_CP_ID, WLAN_SBLOCK_CH, &blk, 0);
		if (ret) {
			dev_dbg(&priv->ndev->dev, "no more sblock to read\n");
			break;
		}
#ifdef CONFIG_SPRDWL_FW_ZEROCOPY
		offset = *(u8 *)blk.addr;
		length = blk.length - 2 - offset;
#else
		length = blk.length;
#endif
		/*16 bytes align */
		skb = dev_alloc_skb(length + NET_IP_ALIGN);
		if (!skb) {
			dev_err(&priv->ndev->dev,
				"Failed to allocate skbuff!\n");
			priv->ndev->stats.rx_dropped++;
			goto rx_failed;
		}
#ifdef CONFIG_SPRDWL_FW_ZEROCOPY
		data = (struct wlan_sblock_recv_data *)(blk.addr + 2 + offset);
#else
		data = (struct wlan_sblock_recv_data *)blk.addr;
#endif

		if (data->is_encrypted == 1) {
			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) {
				u8 snap_header[6] = { 0xaa, 0xaa, 0x03,
					0x00, 0x00, 0x00
				};
				skb_reserve(skb, NET_IP_ALIGN);
				decryp_data_len = wlan_rx_wapi_decryption(priv,
						   (u8 *)&data->u2.encrypt,
						   data->u1.encrypt.header_len,
						   (length -
						   sizeof(data->is_encrypted) -
						   sizeof(data->u1) -
						   data->u1.encrypt.header_len),
						   (skb->data + 12));
				if (decryp_data_len == 0) {
					dev_err(&priv->ndev->dev,
						"Failed to decrypt WAPI data!\n");
					priv->ndev->stats.rx_dropped++;
					dev_kfree_skb(skb);
					goto rx_failed;
				}
				if (memcmp((skb->data + 12), snap_header,
					   sizeof(snap_header)) == 0) {
					skb_reserve(skb, 6);
					/* copy the eth address from eth header,
					 * but not copy eth type
					 */
					memcpy(skb->data,
					       data->u2.encrypt.
					       mac_header.addr1, 6);
					memcpy(skb->data + 6,
					       data->u2.encrypt.
					       mac_header.addr2, 6);
					skb_put(skb, (decryp_data_len + 6));
				} else {
					/* copy eth header */
					memcpy(skb->data,
					       data->u2.encrypt.
					       mac_header.addr3, 6);
					memcpy(skb->data + 6,
					       data->u2.encrypt.
					       mac_header.addr2, 6);
					skb_put(skb, (decryp_data_len + 12));
				}
			} else {
				dev_err(&priv->ndev->dev,
					"wrong encryption data!\n");
				priv->ndev->stats.rx_dropped++;
				dev_kfree_skb(skb);
				goto rx_failed;
			}
		} else if (data->is_encrypted == 0) {
			skb_reserve(skb, NET_IP_ALIGN);
			/* dec the first encrypt byte */
			memcpy(skb->data, (u8 *)&data->u2,
			       (length - sizeof(data->is_encrypted) -
				sizeof(data->u1)));
			skb_put(skb,
				(length - sizeof(data->is_encrypted) -
				 sizeof(data->u1)));
		} else {
			dev_err(&priv->ndev->dev,
				"wrong data fromat recieved!\n");
			priv->ndev->stats.rx_dropped++;
			dev_kfree_skb(skb);
			goto rx_failed;
		}

#ifdef DUMP_RECEIVE_PACKET
		print_hex_dump(KERN_DEBUG, "receive packet: ",
			       DUMP_PREFIX_OFFSET, 16, 1, skb->data, skb->len,
			       0);
#endif
		skb->dev = priv->ndev;
		skb->protocol = eth_type_trans(skb, priv->ndev);
		/* CHECKSUM_UNNECESSARY not supported by our hardware */
		/* skb->ip_summed = CHECKSUM_UNNECESSARY; */

		priv->ndev->stats.rx_packets++;
		priv->ndev->stats.rx_bytes += skb->len;

		napi_gro_receive(napi, skb);

rx_failed:
		ret = sblock_release(WLAN_CP_ID, WLAN_SBLOCK_CH, &blk);
		if (ret)
			dev_err(&priv->ndev->dev,
				"Failed to release sblock (%d)!\n", ret);
	}
	if (work_done < budget)
		napi_complete(napi);

	return work_done;
}