void hdlc_netif_rx(hdlc_device *hdlc, struct sk_buff *skb, int dlci) { skb->mac.raw=skb->data; if (mode_is(hdlc, MODE_SOFT)) { if (mode_is(hdlc, MODE_FR)) { fr_netif(hdlc, skb); return; } else if (mode_is(hdlc, MODE_CISCO)) { cisco_netif(hdlc, skb); return; } else if (mode_is(hdlc, MODE_PPP)) { hdlc->stats.rx_bytes+=skb->len; hdlc->stats.rx_packets++; skb->protocol=htons(ETH_P_WAN_PPP); skb->dev=hdlc_to_dev(hdlc); netif_rx(skb); return; } } else { /* protocol support in hardware/firmware */ hdlc->stats.rx_bytes+=skb->len; hdlc->stats.rx_packets++; if (mode_is(hdlc, MODE_HDLC)) skb->protocol=htons(ETH_P_IP); /* otherwise protocol set by hw driver */ if (mode_is(hdlc, MODE_FR)) { pvc_device *pvc=find_pvc(hdlc, dlci); if (!pvc) { /* packet from nonexistent PVC */ hdlc->stats.rx_errors++; dev_kfree_skb(skb); } pvc->stats.rx_bytes+=skb->len; pvc->stats.rx_packets++; skb->dev=&pvc->netdev; } else skb->dev=hdlc_to_dev(hdlc); netif_rx(skb); return; } hdlc->stats.rx_errors++; /* unsupported mode */ dev_kfree_skb(skb); }
void hdlc_netif_rx(hdlc_device *hdlc, struct sk_buff *skb) { /* skb contains raw HDLC frame, in both hard- and software modes */ skb->mac.raw = skb->data; switch(hdlc->mode & MODE_MASK) { case MODE_HDLC: skb->protocol = htons(ETH_P_IP); skb->dev = hdlc_to_dev(hdlc); netif_rx(skb); return; case MODE_FR: fr_netif(hdlc, skb); return; case MODE_CISCO: cisco_netif(hdlc, skb); return; #ifdef CONFIG_HDLC_PPP case MODE_PPP: #if 0 sppp_input(hdlc_to_dev(hdlc), skb); #else skb->protocol = htons(ETH_P_WAN_PPP); skb->dev = hdlc_to_dev(hdlc); netif_rx(skb); #endif return; #endif #ifdef CONFIG_HDLC_X25 case MODE_X25: skb->dev = hdlc_to_dev(hdlc); if (lapb_data_received(hdlc, skb) == LAPB_OK) return; break; #endif } hdlc->stats.rx_errors++; dev_kfree_skb_any(skb); }