コード例 #1
0
static int sipc4_fmt_rx(struct sipc4_rx_data *data)
{
	struct net_device *dev = data->dev;
	struct sk_buff *skb = data->skb;
	int ch = sipc4_get_hdlc_ch(skb->data, SIPC4_FMT);
	int control = sipc4_get_hdlc_control(skb->data, SIPC4_FMT);
	int info_id = control & FMT_INFOID_MASK;

	/* Remove header */
	skb_pull(skb, sipc4_get_header_size(SIPC4_FMT));

	if (control & FMT_MORE_BIT) {
		skb_queue_tail(&fmt_multi_list[info_id], skb);
		return 0;
	}

	if (fmt_multi_list[info_id].qlen) {
		/* TODO: multi frame */
		;
	}

	sipc4_netif_rx(dev, skb, SIPC4_RES(SIPC4_FMT, ch));

	return 0;
}
コード例 #2
0
static int sipc4_rfs_rx(struct sipc4_rx_data *data)
{
	struct net_device *dev = data->dev;
	struct sk_buff *skb = data->skb;
	struct sipc_rx_hdr *hdr = data->rx_hdr;
	int ch = sipc4_get_hdlc_ch(hdr->hdr, SIPC4_RFS);

	return sipc4_netif_rx(dev, skb, SIPC4_RES(SIPC4_RFS, ch));
}
コード例 #3
0
static int sipc4_rfs_rx(struct sipc4_rx_data *data)
{
	struct net_device *dev = data->dev;
	struct sk_buff *skb = data->skb;
	struct sipc4_rx_frag *frag = (struct sipc4_rx_frag *)skb->cb;
	int ch = sipc4_get_hdlc_ch(skb->data, SIPC4_RFS);

	/* Remove header */
	if (frag->data_len)
		skb_pull(skb, sipc4_get_header_size(SIPC4_RFS));

	return sipc4_netif_rx(dev, skb, SIPC4_RES(SIPC4_RFS, ch));
}
コード例 #4
0
static int sipc4_raw_rx(struct sipc4_rx_data *data)
{
	struct net_device *dev = data->dev;
	struct sk_buff *skb = data->skb;
	struct sipc_rx_hdr *hdr = data->rx_hdr;
	int ch = sipc4_get_hdlc_ch(hdr->hdr, SIPC4_RAW);

	/* check pdp channel */
	if (ch >= CHID_PSD_DATA1 && ch <= CHID_PSD_DATA15)
		pdp_netif_rx(dev, skb, ch);
	else
		sipc4_netif_rx(dev, skb, SIPC4_RES(SIPC4_RAW, ch));

	return 0;
}
コード例 #5
0
static int sipc4_raw_rx(struct sipc4_rx_data *data,
		const __be16 protocol)
{
	struct net_device *dev = data->dev;
	struct sk_buff *skb = data->skb;
	int ch = sipc4_get_hdlc_ch(skb->data, SIPC4_RAW);

	/* Remove header */
	skb_pull(skb, sipc4_get_header_size(SIPC4_RAW));

	/* check pdp channel */
	if (ch >= (CHID_PSD_DATA1) && ch <= CHID_PSD_DATA15)
		pdp_netif_rx(dev, skb, ch, protocol);
	else
		sipc4_netif_rx(dev, skb, SIPC4_RES(SIPC4_RAW, ch));

	return 0;
}
コード例 #6
0
static int sipc4_fmt_rx(struct sipc4_rx_data *data)
{
	struct net_device *dev = data->dev;
	struct sk_buff *skb = data->skb;
	struct sipc_rx_hdr *hdr = data->rx_hdr;
	int ch = sipc4_get_hdlc_ch(hdr->hdr, SIPC4_FMT);
	int control = sipc4_get_hdlc_control(hdr->hdr, SIPC4_FMT);
	int info_id = control & FMT_INFOID_MASK;

	if (control & FMT_MORE_BIT) {
		skb_queue_tail(&fmt_multi_list[info_id], skb);
		return 0;
	}

	if (fmt_multi_list[info_id].qlen) {
		/* TODO: multi frame */
		;
	}

	sipc4_netif_rx(dev, skb, SIPC4_RES(SIPC4_FMT, ch));

	return 0;
}
コード例 #7
0
static int sipc4_hdlc_rx(struct sipc4_rx_data *data)
{
	int rest = data->size;
	char *buf = page_address(data->page);
	int len;
	int err;

	static __be16 protocol;
	int ch;

	char *ptr = buf;
	int size = rest;
	int pos = 0;
	int retrycnt = 0;

	if (rest <= 0)
		goto end;

next_frame:
	err = len = sipc4_check_header(data, buf, rest);
	if (err < 0) {
		_debug_sipc4_print(data, ptr, pos);
		goto end;
	}

	buf += len;
	rest -= len;
	pos += len;

	if (rest == 0)
		goto end;

	if (rest < 0) {
		pr_err("err - r:%d, l:%d, t: %d (%d)\n",
				rest, len, retrycnt, __LINE__);
		_debug_sipc4_print(data, ptr, pos);
		goto end;
	}

	if (data->format == SIPC4_RAW && len != 0) {
		ch = sipc4_get_hdlc_ch(data->skb->data, data->format);
		if (ch >= (CHID_PSD_DATA1) && ch <= CHID_PSD_DATA15) {
			if ((*buf & 0xF0) == 0x60)
				protocol = htons(ETH_P_IPV6);
			else if ((*buf & 0xF0) == 0x40)
				protocol = htons(ETH_P_IP);
			else {
				err = -EINVAL;
				pr_err("err - ip ver\n");
				_debug_sipc4_print(data, ptr, pos);
				goto end;
			}
		}
	}

	err = len = sipc4_check_data(data, buf, rest, protocol);
	if (err < 0) {
		pr_err("err - sipc4 data\n");
		_debug_sipc4_print(data, ptr, pos);
		goto end;
	}
	buf += len;
	rest -= len;
	pos += len;
	if (rest == 0)	/* this packet is splitted */
		goto end;

	if (rest < 0) {
		pr_err("err - r:%d, l:%d, t: %d (%d)\n",
				rest, len, retrycnt, __LINE__);
		_debug_sipc4_print(data, ptr, pos);
		goto end;
	}

	err = len = sipc4_check_hdlc_end(data, buf, size);
	if (err < 0) {
		pr_err("err - r:%d, l:%d, t: %d (%d)\n",
				rest, len, retrycnt, __LINE__);
		_debug_sipc4_print(data, ptr, pos);
		goto end;
	}
	buf += len;
	rest -= len;
	pos += len;
	if (rest < 0) {
		pr_err("err - r:%d, l:%d, t: %d (%d)\n",
				rest, len, retrycnt, __LINE__);
		_debug_sipc4_print(data, ptr, pos);
		goto end;
	}

	err = sipc4_hdlc_format_rx(data, protocol);
	if (err < 0) {
		pr_err("err - hdlc rx\n");
		_debug_sipc4_print(data, ptr, pos);
		goto end;
	}

	data->skb = NULL;

	if (rest) {
		retrycnt++;
		goto next_frame;
	}

end:
	netdev_free_page(data->dev, data->page);

	if (rest < 0)
		err = -ERANGE;

	if (err < 0 && data->skb) {
		dev_kfree_skb_any(data->skb);
		data->skb = NULL;
	}

	return err;
}