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; }
int sipc4_rx(struct sipc4_rx_data *data) { struct net_device *dev = data->dev; struct sk_buff *skb; /* non HDLC frame */ if (!(data->flags & SIPC4_RX_HDLC)) { int ch = SIPC4_NOT_HDLC_CH; /* get socket buffer */ if (!data->skb) { skb = sipc4_alloc_skb(dev, 0); if (!skb) return -ENOMEM; data->skb = skb; } else skb = data->skb; /* handle data */ skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, data->page, 0, data->size); /* rx data */ if (data->flags & SIPC4_RX_LAST) { data->skb = NULL; sipc4_netif_rx(dev, skb, SIPC4_RES(SIPC4_FMT, ch)); } return 0; } return sipc4_hdlc_rx(data); }
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)); }
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)); }
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; }
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; }
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; }