/*
 * dvb_net.c
 *
 * Copyright (C) 2001 Convergence integrated media GmbH
 *                    Ralph Metzler <ralph@convergence.de>
 * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
 *
 * ULE Decapsulation code:
 * Copyright (C) 2003, 2004 gcs - Global Communication & Services GmbH.
 *                      and Department of Scientific Computing
 *                          Paris Lodron University of Salzburg.
 *                          Hilmar Linder <hlinder@cosy.sbg.ac.at>
 *                      and Wolfram Stering <wstering@cosy.sbg.ac.at>
 *
 * ULE Decaps according to RFC 4326.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
 */

/*
 * ULE ChangeLog:
 * Feb 2004: hl/ws v1: Implementing draft-fair-ipdvb-ule-01.txt
 *
 * Dec 2004: hl/ws v2: Implementing draft-ietf-ipdvb-ule-03.txt:
 *                       ULE Extension header handling.
 *                     Bugreports by Moritz Vieth and Hanno Tersteegen,
 *                       Fraunhofer Institute for Open Communication Systems
 *                       Competence Center for Advanced Satellite Communications.
 *                     Bugfixes and robustness improvements.
 *                     Filtering on dest MAC addresses, if present (D-Bit = 0)
 *                     ULE_DEBUG compile-time option.
 * Apr 2006: cp v3:    Bugfixes and compliency with RFC 4326 (ULE) by
 *                       Christian Praehauser <cpraehaus@cosy.sbg.ac.at>,
 *                       Paris Lodron University of Salzburg.
 */

/*
 * FIXME / TODO (dvb_net.c):
 *
 * Unloading does not work for 2.6.9 kernels: a refcount doesn't go to zero.
 *
 */

#define pr_fmt(fmt) "dvb_net: " fmt

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/dvb/net.h>
#include <linux/uio.h>
#include <linux/uaccess.h>
#include <linux/crc32.h>
#include <linux/mutex.h>
#include <linux/sched.h>

#include "dvb_demux.h"
#include "dvb_net.h"

static inline __u32 iov_crc32( __u32 c, struct kvec *iov, unsigned int cnt )
{
	unsigned int j;
	for (j = 0; j < cnt; j++)
		c = crc32_be( c, iov[j].iov_base, iov[j].iov_len );
	return c;
}


#define DVB_NET_MULTICAST_MAX 10

#undef ULE_DEBUG

#ifdef ULE_DEBUG

static void hexdump(const unsigned char *buf, unsigned short len)
{
	print_hex_dump_debug("", DUMP_PREFIX_OFFSET, 16, 1, buf, len, true);
}

#endif

struct dvb_net_priv {
	int in_use;
	u16 pid;
	struct net_device *net;
	struct dvb_net *host;
	struct dmx_demux *demux;
	struct dmx_section_feed *secfeed;
	struct dmx_section_filter *secfilter;
	struct dmx_ts_feed *tsfeed;
	int multi_num;
	struct dmx_section_filter *multi_secfilter[DVB_NET_MULTICAST_MAX];
	unsigned char multi_macs[DVB_NET_MULTICAST_MAX][6];
	int rx_mode;
#define RX_MODE_UNI 0
#define RX_MODE_MULTI 1
#define RX_MODE_ALL_MULTI 2
#define RX_MODE_PROMISC 3
	struct work_struct set_multicast_list_wq;
	struct work_struct restart_net_feed_wq;
	unsigned char feedtype;			/* Either FEED_TYPE_ or FEED_TYPE_ULE */
	int need_pusi;				/* Set to 1, if synchronization on PUSI required. */
	unsigned char tscc;			/* TS continuity counter after sync on PUSI. */
	struct sk_buff *ule_skb;		/* ULE SNDU decodes into this buffer. */
	unsigned char *ule_next_hdr;		/* Pointer into skb to next ULE extension header. */
	unsigned short ule_sndu_len;		/* ULE SNDU length in bytes, w/o D-Bit. */
	unsigned short ule_sndu_type;		/* ULE SNDU type field, complete. */
	unsigned char ule_sndu_type_1;		/* ULE SNDU type field, if split across 2 TS cells. */
	unsigned char ule_dbit;			/* Whether the DestMAC address present
						 * or not (bit is set). */
	unsigned char ule_bridged;		/* Whether the ULE_BRIDGED extension header was found. */
	int ule_sndu_remain;			/* Nr. of bytes still required for current ULE SNDU. */
	unsigned long ts_count;			/* Current ts cell counter. */
	struct mutex mutex;
};


/**
 *	Determine the packet's protocol ID. The rule here is that we
 *	assume 802.3 if the type field is short enough to be a length.
 *	This is normal practice and works for any 'now in use' protocol.
 *
 *  stolen from eth.c out of the linux kernel, hacked for dvb-device
 *  by Michael Holzt <kju@debian.org>
 */
static __be16 dvb_net_eth_type_trans(struct sk_buff *skb,
				      struct net_device *dev)
{
	struct ethhdr *eth;
	unsigned char *rawp;

	skb_reset_mac_header(skb);
	skb_pull(skb,dev->hard_header_len);
	eth = eth_hdr(skb);

	if (*eth->h_dest & 1) {
		if(ether_addr_equal(eth->h_dest,dev->broadcast))
			skb->pkt_type=PACKET_BROADCAST;
		else
			skb->pkt_type=PACKET_MULTICAST;
	}

	if (ntohs(eth->h_proto) >= ETH_P_802_3_MIN)
		return eth->h_proto;

	rawp = skb->data;

	/**
	 *	This is a magic hack to spot IPX packets. Older Novell breaks
	 *	the protocol design and runs IPX over 802.3 without an 802.2 LLC
	 *	layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
	 *	won't work for fault tolerant netware but does for the rest.
	 */
	if (*(unsigned short *)rawp == 0xFFFF)
		return htons(ETH_P_802_3);

	/**
	 *	Real 802.2 LLC
	 */
	return htons(ETH_P_802_2);
}

#define TS_SZ	188
#define TS_SYNC	0x47
#define TS_TEI	0x80
#define TS_SC	0xC0
#define TS_PUSI	0x40
#define TS_AF_A	0x20
#define TS_AF_D	0x10

/* ULE Extension Header handlers. */

#define ULE_TEST	0
#define ULE_BRIDGED	1

#define ULE_OPTEXTHDR_PADDING 0

static int ule_test_sndu( struct dvb_net_priv *p )
{
	return -1;
}

static int ule_bridged_sndu( struct dvb_net_priv *p )
{
	struct ethhdr *hdr = (struct ethhdr*) p->ule_next_hdr;
	if(ntohs(hdr->h_proto) < ETH_P_802_3_MIN) {
		int framelen = p->ule_sndu_len - ((p->ule_next_hdr+sizeof(struct ethhdr)) - p->ule_skb->data);
		/* A frame Type < ETH_P_802_3_MIN for a bridged frame, introduces a LLC Length field. */
		if(framelen != ntohs(hdr->h_proto)) {
			return -1;
		}
	}
	/* Note:
	 * From RFC4326:
	 *  "A bridged SNDU is a Mandatory Extension Header of Type 1.
	 *   It must be the final (or only) extension header specified in the header chain of a SNDU."
	 * The 'ule_bridged' flag will cause the extension header processing loop to terminate.
	 */
	p->ule_bridged = 1;
	return 0;
}

static int ule_exthdr_padding(struct dvb_net_priv *p)
{
	return 0;
}

/** Handle ULE extension headers.
 *  Function is called after a successful CRC32 verification of an ULE SNDU to complete its decoding.
 *  Returns: >= 0: nr. of bytes consumed by next extension header
 *	     -1:   Mandatory extension header that is not recognized or TEST SNDU; discard.
 */
static int handle_one_ule_extension( struct dvb_net_priv *p )
{
	/* Table of mandatory extension header handlers.  The header type is the index. */
	static int (*ule_mandatory_ext_handlers[255])( struct dvb_net_priv *p ) =
		{ [0] = ule_test_sndu, [1] = ule_bridged_sndu, [2] = NULL,  };

	/* Table of optional extension header handlers.  The header type is the index. */
	static int (*ule_optional_ext_handlers[255])( struct dvb_net_priv *p ) =
		{ [0] = ule_exthdr_padding, [1] = NULL, };

	int ext_len = 0;
	unsigned char hlen = (p->ule_sndu_type & 0x0700) >> 8;
	unsigned char htype = p->ule_sndu_type & 0x00FF;

	/* Discriminate mandatory and optional extension headers. */
	if (hlen == 0) {
		/* Mandatory extension header */
		if (ule_mandatory_ext_handlers[htype]) {
			ext_len = ule_mandatory_ext_handlers[htype]( p );
			if(ext_len >= 0) {
				p->ule_next_hdr += ext_len;
				if (!p->ule_bridged) {
					p->ule_sndu_type = ntohs(*(__be16 *)p->ule_next_hdr);
					p->ule_next_hdr += 2;
				} else {
					p->ule_sndu_type = ntohs(*(__be16 *)(p->ule_next_hdr + ((p->ule_dbit ? 2 : 3) * ETH_ALEN)));
					/* This assures the extension handling loop will terminate. */
				}
			}
			// else: extension handler failed or SNDU should be discarded
		} else
			ext_len = -1;	/* SNDU has to be discarded. */
	} else {
		/* Optional extension header.  Calculate the length. */
		ext_len = hlen << 1;
		/* Process the optional extension header according to its type. */
		if (ule_optional_ext_handlers[htype])
			(void)ule_optional_ext_handlers[htype]( p );
		p->ule_next_hdr += ext_len;
		p->ule_sndu_type = ntohs( *(__be16 *)(p->ule_next_hdr-2) );
		/*
		 * note: the length of the next header type is included in the
		 * length of THIS optional extension header
		 */
	}

	return ext_len;
}

static int handle_ule_extensions( struct dvb_net_priv *p )
{
	int total_ext_len = 0, l;

	p->ule_next_hdr = p->ule_skb->data;
	do {
		l = handle_one_ule_extension( p );
		if (l < 0)
			return l;	/* Stop extension header processing and discard SNDU. */
		total_ext_len += l;
#ifdef ULE_DEBUG
		pr_debug("ule_next_hdr=%p, ule_sndu_type=%i, l=%i, total_ext_len=%i\n",
			 p->ule_next_hdr, (int)p->ule_sndu_type,
			 l, total_ext_len);
#endif

	} while (p->ule_sndu_type < ETH_P_802_3_MIN);

	return total_ext_len;
}


/** Prepare for a new ULE SNDU: reset the decoder state. */
static inline void reset_ule( struct dvb_net_priv *p )
{
	p->ule_skb = NULL;
	p->ule_next_hdr = NULL;
	p->ule_sndu_len = 0;
	p->ule_sndu_type = 0;
	p->ule_sndu_type_1 = 0;
	p->ule_sndu_remain = 0;
	p->ule_dbit = 0xFF;
	p->ule_bridged = 0;
}

/**
 * Decode ULE SNDUs according to draft-ietf-ipdvb-ule-03.txt from a sequence of
 * TS cells of a single PID.
 */

struct dvb_net_ule_handle {
	struct net_device *dev;
	struct dvb_net_priv *priv;
	struct ethhdr *ethh;
	const u8 *buf;
	size_t buf_len;
	unsigned long skipped;
	const u8 *ts, *ts_end, *from_where;
	u8 ts_remain, how_much, new_ts;
	bool error;
#ifdef ULE_DEBUG
	/*
	 * The code inside ULE_DEBUG keeps a history of the
	 * last 100 TS cells processed.
	 */
	static unsigned char ule_hist[100*TS_SZ];
	static unsigned char *ule_where = ule_hist, ule_dump;
#endif
};

static int dvb_net_ule_new_ts_cell(struct dvb_net_ule_handle *h)
{
	/* We are about to process a new TS cell. */

#ifdef ULE_DEBUG
	if (h->ule_where >= &h->ule_hist[100*TS_SZ])
		h->ule_where = h->ule_hist;
	memcpy(h->ule_where, h->ts, TS_SZ);
	if (h->ule_dump) {
		hexdump(h->ule_where, TS_SZ);
		h->ule_dump = 0;
	}
	h->ule_where += TS_SZ;
#endif

	/*
	 * Check TS h->error conditions: sync_byte, transport_error_indicator,
	 * scrambling_control .
	 */
	if ((h->ts[0] != TS_SYNC) || (h->ts[1] & TS_TEI) ||
	    ((h->ts[3] & TS_SC) != 0)) {
		pr_warn("%lu: Invalid TS cell: SYNC %#x, TEI %u, SC %#x.\n",
			h->priv->ts_count, h->ts[0],
			(h->ts[1] & TS_TEI) >> 7,
			(h->ts[3] & TS_SC) >> 6);

		/* Drop partly decoded SNDU, reset state, resync on PUSI. */
		if (h->priv->ule_skb) {
			dev_kfree_skb(h->priv->ule_skb);
			/* Prepare for next SNDU. */
			h->dev->stats.rx_errors++;
			h->dev->stats.rx_frame_errors++;
		}
		reset_ule(h->priv);
		h->priv->need_pusi = 1;

		/* Continue with next TS cell. */
		h->ts += TS_SZ;
		h->priv->ts_count++;
		return 1;
	}

	h->ts_remain = 184;
	h->from_where = h->ts + 4;

	return 0;
}

static int dvb_net_ule_ts_pusi(struct dvb_net_ule_handle *h)
{
	if (h->ts[1] & TS_PUSI) {
		/* Find beginning of first ULE SNDU in current TS cell. */
		/* Synchronize continuity counter. */
		h->priv->tscc = h->ts[3] & 0x0F;
		/* There is a pointer field here. */
		if (h->ts[4] > h->ts_remain) {
			pr_err("%lu: Invalid ULE packet (pointer field %d)\n",
				h->priv->ts_count, h->ts[4]);
			h->ts += TS_SZ;
			h->priv->ts_count++;
			return 1;
		}
		/* Skip to destination of pointer field. */
		h->from_where = &h->ts[5] + h->ts[4];
		h->ts_remain -= 1 + h->ts[4];
		h->skipped = 0;
	} else {
		h->skipped++;
		h->ts += TS_SZ;
		h->priv->ts_count++;
		return 1;
	}

	return 0;
}

static int dvb_net_ule_new_ts(struct dvb_net_ule_handle *h)
{
	/* Check continuity counter. */
	if ((h->ts[3] & 0x0F) == h->priv->tscc)
		h->priv->tscc = (h->priv->tscc + 1) & 0x0F;
	else {
		/* TS discontinuity handling: */
		pr_warn("%lu: TS discontinuity: got %#x, expected %#x.\n",
			h->priv->ts_count, h->ts[3] & 0x0F,
			h->priv->tscc);
		/* Drop partly decoded SNDU, reset state, resync on PUSI. */
		if (h->priv->ule_skb) {
			dev_kfree_skb(h->priv->ule_skb);
			/* Prepare for next SNDU. */
			// reset_ule(h->priv);  moved to below.
			h->dev->stats.rx_errors++;
			h->dev->stats.rx_frame_errors++;
		}
		reset_ule(h->priv);
		/* skip to next PUSI. */
		h->priv->need_pusi = 1;
		return 1;
	}
	/*
	 * If we still have an incomplete payload, but PUSI is
	 * set; some TS cells are missing.
	 * This is only possible here, if we missed exactly 16 TS
	 * cells (continuity counter wrap).
	 */
	if (h->ts[1] & TS_PUSI) {
		if (!h->priv->need_pusi) {
			if (!(*h->from_where < (h->ts_remain-1)) ||
			    *h->from_where != h->priv->ule_sndu_remain) {
				/*
				 * Pointer field is invalid.
				 * Drop this TS cell and any started ULE SNDU.
				 */
				pr_warn("%lu: Invalid pointer field: %u.\n",
					h->priv->ts_count,
					*h->from_where);

				/*
				 * Drop partly decoded SNDU, reset state,
				 * resync on PUSI.
				 */
				if (h->priv->ule_skb) {
					h->error = true;
					dev_kfree_skb(h->priv->ule_skb);
				}

				if (h->error || h->priv->ule_sndu_remain) {
					h->dev->stats.rx_errors++;
					h->dev->stats.rx_frame_errors++;
					h->error = false;
				}

				reset_ule(h->priv);
				h->priv->need_pusi = 1;
				return 1;
			}
			/*
			 * Skip pointer field (we're processing a
			 * packed payload).
			 */
			h->from_where += 1;
			h->ts_remain -= 1;
		} else
			h->priv->need_pusi = 0;

		if (h->priv->ule_sndu_remain > 183) {
			/*
			 * Current SNDU lacks more data than there
			 * could be available in the current TS cell.
			 */
			h->dev->stats.rx_errors++;
			h->dev->stats.rx_length_errors++;
			pr_warn("%lu: Expected %d more SNDU bytes, but got PUSI (pf %d, h->ts_remain %d).  Flushing incomplete payload.\n",
				h->priv->ts_count,
				h->priv->ule_sndu_remain,
				h->ts[4], h->ts_remain);
			dev_kfree_skb(h->priv->ule_skb);
			/* Prepare for next SNDU. */
			reset_ule(h->priv);
			/*
			 * Resync: go to where pointer field points to:
			 * start of next ULE SNDU.
			 */
			h->from_where += h->ts[4];
			h->ts_remain -= h->ts[4];
		}
	}
	return 0;
}


/*
 * Start a new payload with skb.
 * Find ULE header.  It is only guaranteed that the
 * length field (2 bytes) is contained in the current
 * TS.
 * Check h.ts_remain has to be >= 2 here.
 */
static int dvb_net_ule_new_payload(struct dvb_net_ule_handle *h)
{
	if (h->ts_remain < 2) {
		pr_warn("Invalid payload packing: only %d bytes left in TS.  Resyncing.\n",
			h->ts_remain);
		h->priv->ule_sndu_len = 0;
		h->priv->need_pusi = 1;
		h->ts += TS_SZ;
		return 1;
	}

	if (!h->priv->ule_sndu_len) {
		/* Got at least two bytes, thus extrace the SNDU length. */
		h->priv->ule_sndu_len = h->from_where[0] << 8 |
					h->from_where[1];
		if (h->priv->ule_sndu_len & 0x8000) {
			/* D-Bit is set: no dest mac present. */
			h->priv->ule_sndu_len &= 0x7FFF;
			h->priv->ule_dbit = 1;
		} else
			h->priv->ule_dbit = 0;

		if (h->priv->ule_sndu_len < 5) {
			pr_warn("%lu: Invalid ULE SNDU length %u. Resyncing.\n",
				h->priv->ts_count,
				h->priv->ule_sndu_len);
			h->dev->stats.rx_errors++;
			h->dev->stats.rx_length_errors++;
			h->priv->ule_sndu_len = 0;
			h->priv->need_pusi = 1;
			h->new_ts = 1;
			h->ts += TS_SZ;
			h->priv->ts_count++;
			return 1;
		}
		h->ts_remain -= 2;	/* consume the 2 bytes SNDU length. */
		h->from_where += 2;
	}

	h->priv->ule_sndu_remain = h->priv->ule_sndu_len + 2;
	/*
	 * State of current TS:
	 *   h->ts_remain (remaining bytes in the current TS cell)
	 *   0	ule_type is not available now, we need the next TS cell
	 *   1	the first byte of the ule_type is present
	 * >=2	full ULE header present, maybe some payload data as well.
	 */
	switch (h->ts_remain) {
	case 1:
		h->priv->ule_sndu_remain--;
		h->priv->ule_sndu_type = h->from_where[0] << 8;

		/* first byte of ule_type is set. */
		h->priv->ule_sndu_type_1 = 1;
		h->ts_remain -= 1;
		h->from_where += 1;
		/* fallthrough */
	case 0:
		h->new_ts = 1;
		h->ts += TS_SZ;
		h->priv->ts_count++;
		return 1;

	default: /* complete ULE header is present in current TS. */
		/* Extract ULE type field. */
		if (h->priv->ule_sndu_type_1) {
			h->priv->ule_sndu_type_1 = 0;
			h->priv->ule_sndu_type |= h->from_where[0];
			h->from_where += 1; /* points to payload start. */
			h->ts_remain -= 1;
		} else {
			/* Complete type is present in new TS. */
			h->priv->ule_sndu_type = h->from_where[0] << 8 |
						 h->from_where[1];
			h->from_where += 2; /* points to payload start. */
			h->ts_remain -= 2;
		}
		break;
	}

	/*
	 * Allocate the skb (decoder target buffer) with the correct size,
	 * as follows:
	 *
	 * prepare for the largest case: bridged SNDU with MAC address
	 * (dbit = 0).
	 */
	h->priv->ule_skb = dev_alloc_skb(h->priv->ule_sndu_len +
					 ETH_HLEN + ETH_ALEN);
	if (!h->priv->ule_skb) {
		pr_notice("%s: Memory squeeze, dropping packet.\n",
			  h->dev->name);
		h->dev->stats.rx_dropped++;
		return -1;
	}

	/* This includes the CRC32 _and_ dest mac, if !dbit. */
	h->priv->ule_sndu_remain = h->priv->ule_sndu_len;
	h->priv->ule_skb->dev = h->dev;
	/*
	 * Leave space for Ethernet or bridged SNDU header
	 * (eth hdr plus one MAC addr).
	 */
	skb_reserve(h->priv->ule_skb, ETH_HLEN + ETH_ALEN);

	return 0;
}


static int dvb_net_ule_should_drop(struct dvb_net_ule_handle *h)
{
	static const u8 bc_addr[ETH_ALEN] = { [0 ... ETH_ALEN - 1] = 0xff };

	/*
	 * The destination MAC address is the next data in the skb.  It comes
	 * before any extension headers.
	 *
	 * Check if the payload of this SNDU should be passed up the stack.
	 */
	if (h->priv->rx_mode == RX_MODE_PROMISC)
		return 0;

	if (h->priv->ule_skb->data[0] & 0x01) {
		/* multicast or broadcast */
		if (!ether_addr_equal(h->priv->ule_skb->data, bc_addr)) {
			/* multicast */
			if (h->priv->rx_mode == RX_MODE_MULTI) {
				int i;

				for (i = 0; i < h->priv->multi_num &&
				     !ether_addr_equal(h->priv->ule_skb->data,
						       h->priv->multi_macs[i]);
				     i++)
					;
				if (i == h->priv->multi_num)
					return 1;
			} else if (h->priv->rx_mode != RX_MODE_ALL_MULTI)
				return 1; /* no broadcast; */
			/*
			 * else:
			 * all multicast mode: accept all multicast packets
			 */
		}
		/* else: broadcast */
	} else if (!ether_addr_equal(h->priv->ule_skb->data, h->dev->dev_addr))
		return 1;

	return 0;
}


static void dvb_net_ule_check_crc(struct dvb_net_ule_handle *h,
				  u32 ule_crc, u32 expected_crc)
{
	u8 dest_addr[ETH_ALEN];

	if (ule_crc != expected_crc) {
		pr_warn("%lu: CRC32 check FAILED: %08x / %08x, SNDU len %d type %#x, ts_remain %d, next 2: %x.\n",
			h->priv->ts_count, ule_crc, expected_crc,
			h->priv->ule_sndu_len, h->priv->ule_sndu_type,
			h->ts_remain,
			h->ts_remain > 2 ?
				*(unsigned short *)h->from_where : 0);

	#ifdef ULE_DEBUG
		hexdump(iov[0].iov_base, iov[0].iov_len);
		hexdump(iov[1].iov_base, iov[1].iov_len);
		hexdump(iov[2].iov_base, iov[2].iov_len);

		if (h->ule_where == h->ule_hist) {
			hexdump(&h->ule_hist[98*TS_SZ], TS_SZ);
			hexdump(&h->ule_hist[99*TS_SZ], TS_SZ);
		} else if (h->ule_where == &h->ule_hist[TS_SZ]) {
			hexdump(&h->ule_hist[99*TS_SZ], TS_SZ);
			hexdump(h->ule_hist, TS_SZ);
		} else {
			hexdump(h->ule_where - TS_SZ - TS_SZ, TS_SZ);
			hexdump(h->ule_where - TS_SZ, TS_SZ);
		}
		h->ule_dump = 1;
	#endif

		h->dev->stats.rx_errors++;
		h->dev->stats.rx_crc_errors++;
		dev_kfree_skb(h->priv->ule_skb);

		return;
	}

	/* CRC32 verified OK. */

	/* CRC32 was OK, so remove it from skb. */
	h->priv->ule_skb->tail -= 4;
	h->priv->ule_skb->len -= 4;

	if (!h->priv->ule_dbit) {
		if (dvb_net_ule_should_drop(h)) {
#ifdef ULE_DEBUG
			netdev_dbg(h->dev,
				   "Dropping SNDU: MAC destination address does not match: dest addr: %pM, h->dev addr: %pM\n",
				   h->priv->ule_skb->data, h->dev->dev_addr);
#endif
			dev_kfree_skb(h->priv->ule_skb);
			return;
		}

		skb_copy_from_linear_data(h->priv->ule_skb, dest_addr,
					  ETH_ALEN);
		skb_pull(h->priv->ule_skb, ETH_ALEN);
	}

	/* Handle ULE Extension Headers. */
	if (h->priv->ule_sndu_type < ETH_P_802_3_MIN) {
		/* There is an extension header.  Handle it accordingly. */
		int l = handle_ule_extensions(h->priv);

		if (l < 0) {
			/*
			 * Mandatory extension header unknown or TEST SNDU.
			 * Drop it.
			 */

			// pr_warn("Dropping SNDU, extension headers.\n" );
			dev_kfree_skb(h->priv->ule_skb);
			return;
		}
		skb_pull(h->priv->ule_skb, l);
	}

	/*
	 * Construct/assure correct ethernet header.
	 * Note: in bridged mode (h->priv->ule_bridged != 0)
	 * we already have the (original) ethernet
	 * header at the start of the payload (after
	 * optional dest. address and any extension
	 * headers).
	 */
	if (!h->priv->ule_bridged) {
		skb_push(h->priv->ule_skb, ETH_HLEN);
		h->ethh = (struct ethhdr *)h->priv->ule_skb->data;
		if (!h->priv->ule_dbit) {
			/*
			 * dest_addr buffer is only valid if
			 * h->priv->ule_dbit == 0
			 */
			memcpy(h->ethh->h_dest, dest_addr, ETH_ALEN);
			eth_zero_addr(h->ethh->h_source);
		} else /* zeroize source and dest */
			memset(h->ethh, 0, ETH_ALEN * 2);

		h->ethh->h_proto = htons(h->priv->ule_sndu_type);
	}
	/* else:  skb is in correct state; nothing to do. */
	h->priv->ule_bridged = 0;

	/* Stuff into kernel's protocol stack. */
	h->priv->ule_skb->protocol = dvb_net_eth_type_trans(h->priv->ule_skb,
							   h->dev);
	/*
	 * If D-bit is set (i.e. destination MAC address not present),
	 * receive the packet anyhow.
	 */
#if 0
	if (h->priv->ule_dbit && skb->pkt_type == PACKET_OTHERHOST)
		h->priv->ule_skb->pkt_type = PACKET_HOST;
#endif
	h->dev->stats.rx_packets++;
	h->dev->stats.rx_bytes += h->priv->ule_skb->len;
	netif_rx(h->priv->ule_skb);
}

static void dvb_net_ule(struct net_device *dev, const u8 *buf, size_t buf_len)
{
	int ret;
	struct dvb_net_ule_handle h = {
		.dev = dev,
		.buf = buf,
		.buf_len = buf_len,
		.skipped = 0L,
		.ts = NULL,
		.ts_end = NULL,
		.from_where = NULL,
		.ts_remain = 0,
		.how_much = 0,
		.new_ts = 1,
		.ethh = NULL,
		.error = false,
#ifdef ULE_DEBUG
		.ule_where = ule_hist,
#endif
	};

	/*
	 * For all TS cells in current buffer.
	 * Appearently, we are called for every single TS cell.
	 */
	for (h.ts = h.buf, h.ts_end = h.buf + h.buf_len;
	     h.ts < h.ts_end; /* no incr. */) {
		if (h.new_ts) {
			/* We are about to process a new TS cell. */
			if (dvb_net_ule_new_ts_cell(&h))
				continue;
		}

		/* Synchronize on PUSI, if required. */
		if (h.priv->need_pusi) {
			if (dvb_net_ule_ts_pusi(&h))
				continue;
		}

		if (h.new_ts) {
			if (dvb_net_ule_new_ts(&h))
				continue;
		}

		/* Check if new payload needs to be started. */
		if (h.priv->ule_skb == NULL) {
			ret = dvb_net_ule_new_payload(&h);
			if (ret < 0)
				return;
			if (ret)
				continue;
		}

		/* Copy data into our current skb. */
		h.how_much = min(h.priv->ule_sndu_remain, (int)h.ts_remain);
		memcpy(skb_put(h.priv->ule_skb, h.how_much),
		       h.from_where, h.how_much);
		h.priv->ule_sndu_remain -= h.how_much;
		h.ts_remain -= h.how_much;
		h.from_where += h.how_much;

		/* Check for complete payload. */
		if (h.priv->ule_sndu_remain <= 0) {
			/* Check CRC32, we've got it in our skb already. */
			__be16 ulen = htons(h.priv->ule_sndu_len);
			__be16 utype = htons(h.priv->ule_sndu_type);
			const u8 *tail;
			struct kvec iov[3] = {
				{ &ulen, sizeof ulen },
				{ &utype, sizeof utype },
				{ h.priv->ule_skb->data,
				  h.priv->ule_skb->len - 4 }
			};
			u32 ule_crc = ~0L, expected_crc;
			if (h.priv->ule_dbit) {
				/* Set D-bit for CRC32 verification,
				 * if it was set originally. */
				ulen |= htons(0x8000);
			}

			ule_crc = iov_crc32(ule_crc, iov, 3);
			tail = skb_tail_pointer(h.priv->ule_skb);
			expected_crc = *(tail - 4) << 24 |
				       *(tail - 3) << 16 |
				       *(tail - 2) << 8 |
				       *(tail - 1);

			dvb_net_ule_check_crc(&h, ule_crc, expected_crc);

			/* Prepare for next SNDU. */
			reset_ule(h.priv);
		}

		/* More data in current TS (look at the bytes following the CRC32)? */
		if (h.ts_remain >= 2 && *((unsigned short *)h.from_where) != 0xFFFF) {
			/* Next ULE SNDU starts right there. */
			h.new_ts = 0;
			h.priv->ule_skb = NULL;
			h.priv->ule_sndu_type_1 = 0;
			h.priv->ule_sndu_len = 0;
			// pr_warn("More data in current TS: [%#x %#x %#x %#x]\n",
			//	*(h.from_where + 0), *(h.from_where + 1),
			//	*(h.from_where + 2), *(h.from_where + 3));
			// pr_warn("h.ts @ %p, stopped @ %p:\n", h.ts, h.from_where + 0);
			// hexdump(h.ts, 188);
		} else {
			h.new_ts = 1;
			h.ts += TS_SZ;
			h.priv->ts_count++;
			if (h.priv->ule_skb == NULL) {
				h.priv->need_pusi = 1;
				h.priv->ule_sndu_type_1 = 0;
				h.priv->ule_sndu_len = 0;
			}
		}
	}	/* for all available TS cells */
}

static int dvb_net_ts_callback(const u8 *buffer1, size_t buffer1_len,
			       const u8 *buffer2, size_t buffer2_len,
			       struct dmx_ts_feed *feed)
{
	struct net_device *dev = feed->priv;

	if (buffer2)
		pr_warn("buffer2 not NULL: %p.\n", buffer2);
	if (buffer1_len > 32768)
		pr_warn("length > 32k: %zu.\n", buffer1_len);
	/* pr_info("TS callback: %u bytes, %u TS cells @ %p.\n",
		  buffer1_len, buffer1_len / TS_SZ, buffer1); */
	dvb_net_ule(dev, buffer1, buffer1_len);
	return 0;
}


static void dvb_net_sec(struct net_device *dev,
			const u8 *pkt, int pkt_len)
{
	u8 *eth;
	struct sk_buff *skb;
	struct net_device_stats *stats = &dev->stats;
	int snap = 0;

	/* note: pkt_len includes a 32bit checksum */
	if (pkt_len < 16) {
		pr_warn("%s: IP/MPE packet length = %d too small.\n",
			dev->name, pkt_len);
		stats->rx_errors++;
		stats->rx_length_errors++;
		return;
	}
/* it seems some ISPs manage to screw up here, so we have to
 * relax the error checks... */
#if 0
	if ((pkt[5] & 0xfd) != 0xc1) {
		/* drop scrambled or broken packets */
#else
	if ((pkt[5] & 0x3c) != 0x00) {
		/* drop scrambled */
#endif
		stats->rx_errors++;
		stats->rx_crc_errors++;
		return;
	}
	if (pkt[5] & 0x02) {
		/* handle LLC/SNAP, see rfc-1042 */
		if (pkt_len < 24 || memcmp(&pkt[12], "\xaa\xaa\x03\0\0\0", 6)) {
			stats->rx_dropped++;
			return;
		}
		snap = 8;
	}
	if (pkt[7]) {
		/* FIXME: assemble datagram from multiple sections */
		stats->rx_errors++;
		stats->rx_frame_errors++;
		return;
	}

	/* we have 14 byte ethernet header (ip header follows);
	 * 12 byte MPE header; 4 byte checksum; + 2 byte alignment, 8 byte LLC/SNAP
	 */
	if (!(skb = dev_alloc_skb(pkt_len - 4 - 12 + 14 + 2 - snap))) {
		//pr_notice("%s: Memory squeeze, dropping packet.\n", dev->name);
		stats->rx_dropped++;
		return;
	}
	skb_reserve(skb, 2);    /* longword align L3 header */
	skb->dev = dev;

	/* copy L3 payload */
	eth = (u8 *) skb_put(skb, pkt_len - 12 - 4 + 14 - snap);
	memcpy(eth + 14, pkt + 12 + snap, pkt_len - 12 - 4 - snap);

	/* create ethernet header: */
	eth[0]=pkt[0x0b];
	eth[1]=pkt[0x0a];
	eth[2]=pkt[0x09];
	eth[3]=pkt[0x08];
	eth[4]=pkt[0x04];
	eth[5]=pkt[0x03];

	eth[6]=eth[7]=eth[8]=eth[9]=eth[10]=eth[11]=0;

	if (snap) {
		eth[12] = pkt[18];
		eth[13] = pkt[19];
	} else {
		/* protocol numbers are from rfc-1700 or
		 * http://www.iana.org/assignments/ethernet-numbers
		 */
		if (pkt[12] >> 4 == 6) { /* version field from IP header */
			eth[12] = 0x86;	/* IPv6 */
			eth[13] = 0xdd;
		} else {
			eth[12] = 0x08;	/* IPv4 */
			eth[13] = 0x00;
		}
	}

	skb->protocol = dvb_net_eth_type_trans(skb, dev);

	stats->rx_packets++;
	stats->rx_bytes+=skb->len;
	netif_rx(skb);
}

static int dvb_net_sec_callback(const u8 *buffer1, size_t buffer1_len,
		 const u8 *buffer2, size_t buffer2_len,
		 struct dmx_section_filter *filter)
{
	struct net_device *dev = filter->priv;

	/**
	 * we rely on the DVB API definition where exactly one complete
	 * section is delivered in buffer1
	 */
	dvb_net_sec (dev, buffer1, buffer1_len);
	return 0;
}

static int dvb_net_tx(struct sk_buff *skb, struct net_device *dev)
{
	dev_kfree_skb(skb);
	return NETDEV_TX_OK;
}

static u8 mask_normal[6]={0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
static u8 mask_allmulti[6]={0xff, 0xff, 0xff, 0x00, 0x00, 0x00};
static u8 mac_allmulti[6]={0x01, 0x00, 0x5e, 0x00, 0x00, 0x00};
static u8 mask_promisc[6]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

static int dvb_net_filter_sec_set(struct net_device *dev,
		   struct dmx_section_filter **secfilter,
		   u8 *mac, u8 *mac_mask)
{
	struct dvb_net_priv *priv = netdev_priv(dev);
	int ret;

	*secfilter=NULL;
	ret = priv->secfeed->allocate_filter(priv->secfeed, secfilter);
	if (ret<0) {
		pr_err("%s: could not get filter\n", dev->name);
		return ret;
	}

	(*secfilter)->priv=(void *) dev;

	memset((*secfilter)->filter_value, 0x00, DMX_MAX_FILTER_SIZE);
	memset((*secfilter)->filter_mask,  0x00, DMX_MAX_FILTER_SIZE);
	memset((*secfilter)->filter_mode,  0xff, DMX_MAX_FILTER_SIZE);

	(*secfilter)->filter_value[0]=0x3e;
	(*secfilter)->filter_value[3]=mac[5];
	(*secfilter)->filter_value[4]=mac[4];
	(*secfilter)->filter_value[8]=mac[3];
	(*secfilter)->filter_value[9]=mac[2];
	(*secfilter)->filter_value[10]=mac[1];
	(*secfilter)->filter_value[11]=mac[0];

	(*secfilter)->filter_mask[0] = 0xff;
	(*secfilter)->filter_mask[3] = mac_mask[5];
	(*secfilter)->filter_mask[4] = mac_mask[4];
	(*secfilter)->filter_mask[8] = mac_mask[3];
	(*secfilter)->filter_mask[9] = mac_mask[2];
	(*secfilter)->filter_mask[10] = mac_mask[1];
	(*secfilter)->filter_mask[11]=mac_mask[0];

	netdev_dbg(dev, "filter mac=%pM mask=%pM\n", mac, mac_mask);

	return 0;
}

static int dvb_net_feed_start(struct net_device *dev)
{
	int ret = 0, i;
	struct dvb_net_priv *priv = netdev_priv(dev);
	struct dmx_demux *demux = priv->demux;
	unsigned char *mac = (unsigned char *) dev->dev_addr;

	netdev_dbg(dev, "rx_mode %i\n", priv->rx_mode);
	mutex_lock(&priv->mutex);
	if (priv->tsfeed || priv->secfeed || priv->secfilter || priv->multi_secfilter[0])
		pr_err("%s: BUG %d\n", __func__, __LINE__);

	priv->secfeed=NULL;
	priv->secfilter=NULL;
	priv->tsfeed = NULL;

	if (priv->feedtype == DVB_NET_FEEDTYPE_MPE) {
		netdev_dbg(dev, "alloc secfeed\n");
		ret=demux->allocate_section_feed(demux, &priv->secfeed,
					 dvb_net_sec_callback);
		if (ret<0) {
			pr_err("%s: could not allocate section feed\n",
			       dev->name);
			goto error;
		}

		ret = priv->secfeed->set(priv->secfeed, priv->pid, 1);

		if (ret<0) {
			pr_err("%s: could not set section feed\n", dev->name);
			priv->demux->release_section_feed(priv->demux, priv->secfeed);
			priv->secfeed=NULL;
			goto error;
		}

		if (priv->rx_mode != RX_MODE_PROMISC) {
			netdev_dbg(dev, "set secfilter\n");
			dvb_net_filter_sec_set(dev, &priv->secfilter, mac, mask_normal);
		}

		switch (priv->rx_mode) {
		case RX_MODE_MULTI:
			for (i = 0; i < priv->multi_num; i++) {
				netdev_dbg(dev, "set multi_secfilter[%d]\n", i);
				dvb_net_filter_sec_set(dev, &priv->multi_secfilter[i],
						       priv->multi_macs[i], mask_normal);
			}
			break;
		case RX_MODE_ALL_MULTI:
			priv->multi_num=1;
			netdev_dbg(dev, "set multi_secfilter[0]\n");
			dvb_net_filter_sec_set(dev, &priv->multi_secfilter[0],
					       mac_allmulti, mask_allmulti);
			break;
		case RX_MODE_PROMISC:
			priv->multi_num=0;
			netdev_dbg(dev, "set secfilter\n");
			dvb_net_filter_sec_set(dev, &priv->secfilter, mac, mask_promisc);
			break;
		}

		netdev_dbg(dev, "start filtering\n");
		priv->secfeed->start_filtering(priv->secfeed);
	} else if (priv->feedtype == DVB_NET_FEEDTYPE_ULE) {
		ktime_t timeout = ns_to_ktime(10 * NSEC_PER_MSEC);

		/* we have payloads encapsulated in TS */
		netdev_dbg(dev, "alloc tsfeed\n");
		ret = demux->allocate_ts_feed(demux, &priv->tsfeed, dvb_net_ts_callback);
		if (ret < 0) {
			pr_err("%s: could not allocate ts feed\n", dev->name);
			goto error;
		}

		/* Set netdevice pointer for ts decaps callback. */
		priv->tsfeed->priv = (void *)dev;
		ret = priv->tsfeed->set(priv->tsfeed,
					priv->pid, /* pid */
					TS_PACKET, /* type */
					DMX_PES_OTHER, /* pes type */
					timeout    /* timeout */
					);

		if (ret < 0) {
			pr_err("%s: could not set ts feed\n", dev->name);
			priv->demux->release_ts_feed(priv->demux, priv->tsfeed);
			priv->tsfeed = NULL;
			goto error;
		}

		netdev_dbg(dev, "start filtering\n");
		priv->tsfeed->start_filtering(priv->tsfeed);
	} else
		ret = -EINVAL;

error:
	mutex_unlock(&priv->mutex);
	return ret;
}

static int dvb_net_feed_stop(struct net_device *dev)
{
	struct dvb_net_priv *priv = netdev_priv(dev);
	int i, ret = 0;

	mutex_lock(&priv->mutex);
	if (priv->feedtype == DVB_NET_FEEDTYPE_MPE) {
		if (priv->secfeed) {
			if (priv->secfeed->is_filtering) {
				netdev_dbg(dev, "stop secfeed\n");
				priv->secfeed->stop_filtering(priv->secfeed);
			}

			if (priv->secfilter) {
				netdev_dbg(dev, "release secfilter\n");
				priv->secfeed->release_filter(priv->secfeed,
							      priv->secfilter);
				priv->secfilter=NULL;
			}

			for (i=0; i<priv->multi_num; i++) {
				if (priv->multi_secfilter[i]) {
					netdev_dbg(dev, "release multi_filter[%d]\n",
						   i);
					priv->secfeed->release_filter(priv->secfeed,
								      priv->multi_secfilter[i]);
					priv->multi_secfilter[i] = NULL;
				}
			}

			priv->demux->release_section_feed(priv->demux, priv->secfeed);
			priv->secfeed = NULL;
		} else
			pr_err("%s: no feed to stop\n", dev->name);
	} else if (priv->feedtype == DVB_NET_FEEDTYPE_ULE) {
		if (priv->tsfeed) {
			if (priv->tsfeed->is_filtering) {
				netdev_dbg(dev, "stop tsfeed\n");
				priv->tsfeed->stop_filtering(priv->tsfeed);
			}
			priv->demux->release_ts_feed(priv->demux, priv->tsfeed);
			priv->tsfeed = NULL;
		}
		else
			pr_err("%s: no ts feed to stop\n", dev->name);
	} else
		ret = -EINVAL;
	mutex_unlock(&priv->mutex);
	return ret;
}


static int dvb_set_mc_filter(struct net_device *dev, unsigned char *addr)
{
	struct dvb_net_priv *priv = netdev_priv(dev);

	if (priv->multi_num == DVB_NET_MULTICAST_MAX)
		return -ENOMEM;

	memcpy(priv->multi_macs[priv->multi_num], addr, ETH_ALEN);

	priv->multi_num++;
	return 0;
}


static void wq_set_multicast_list (struct work_struct *work)
{
	struct dvb_net_priv *priv =
		container_of(work, struct dvb_net_priv, set_multicast_list_wq);
	struct net_device *dev = priv->net;

	dvb_net_feed_stop(dev);
	priv->rx_mode = RX_MODE_UNI;
	netif_addr_lock_bh(dev);

	if (dev->flags & IFF_PROMISC) {
		netdev_dbg(dev, "promiscuous mode\n");
		priv->rx_mode = RX_MODE_PROMISC;
	} else if ((dev->flags & IFF_ALLMULTI)) {
		netdev_dbg(dev, "allmulti mode\n");
		priv->rx_mode = RX_MODE_ALL_MULTI;
	} else if (!netdev_mc_empty(dev)) {
		struct netdev_hw_addr *ha;

		netdev_dbg(dev, "set_mc_list, %d entries\n",
			   netdev_mc_count(dev));

		priv->rx_mode = RX_MODE_MULTI;
		priv->multi_num = 0;

		netdev_for_each_mc_addr(ha, dev)
			dvb_set_mc_filter(dev, ha->addr);
	}

	netif_addr_unlock_bh(dev);
	dvb_net_feed_start(dev);
}


static void dvb_net_set_multicast_list (struct net_device *dev)
{
	struct dvb_net_priv *priv = netdev_priv(dev);
	schedule_work(&priv->set_multicast_list_wq);
}


static void wq_restart_net_feed (struct work_struct *work)
{
	struct dvb_net_priv *priv =
		container_of(work, struct dvb_net_priv, restart_net_feed_wq);
	struct net_device *dev = priv->net;

	if (netif_running(dev)) {
		dvb_net_feed_stop(dev);
		dvb_net_feed_start(dev);
	}
}


static int dvb_net_set_mac (struct net_device *dev, void *p)
{
	struct dvb_net_priv *priv = netdev_priv(dev);
	struct sockaddr *addr=p;

	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);

	if (netif_running(dev))
		schedule_work(&priv->restart_net_feed_wq);

	return 0;
}


static int dvb_net_open(struct net_device *dev)
{
	struct dvb_net_priv *priv = netdev_priv(dev);

	priv->in_use++;
	dvb_net_feed_start(dev);
	return 0;
}


static int dvb_net_stop(struct net_device *dev)
{
	struct dvb_net_priv *priv = netdev_priv(dev);

	priv->in_use--;
	return dvb_net_feed_stop(dev);
}

static const struct header_ops dvb_header_ops = {
	.create		= eth_header,
	.parse		= eth_header_parse,
};


static const struct net_device_ops dvb_netdev_ops = {
	.ndo_open		= dvb_net_open,
	.ndo_stop		= dvb_net_stop,
	.ndo_start_xmit		= dvb_net_tx,
	.ndo_set_rx_mode	= dvb_net_set_multicast_list,
	.ndo_set_mac_address    = dvb_net_set_mac,
	.ndo_validate_addr	= eth_validate_addr,
};

static void dvb_net_setup(struct net_device *dev)
{
	ether_setup(dev);

	dev->header_ops		= &dvb_header_ops;
	dev->netdev_ops		= &dvb_netdev_ops;
	dev->mtu		= 4096;
	dev->max_mtu		= 4096;

	dev->flags |= IFF_NOARP;
}

static int get_if(struct dvb_net *dvbnet)
{
	int i;

	for (i=0; i<DVB_NET_DEVICES_MAX; i++)
		if (!dvbnet->state[i])
			break;

	if (i == DVB_NET_DEVICES_MAX)
		return -1;

	dvbnet->state[i]=1;
	return i;
}

static int dvb_net_add_if(struct dvb_net *dvbnet, u16 pid, u8 feedtype)
{
	struct net_device *net;
	struct dvb_net_priv *priv;
	int result;
	int if_num;

	if (feedtype != DVB_NET_FEEDTYPE_MPE && feedtype != DVB_NET_FEEDTYPE_ULE)
		return -EINVAL;
	if ((if_num = get_if(dvbnet)) < 0)
		return -EINVAL;

	net = alloc_netdev(sizeof(struct dvb_net_priv), "dvb",
			   NET_NAME_UNKNOWN, dvb_net_setup);
	if (!net)
		return -ENOMEM;

	if (dvbnet->dvbdev->id)
		snprintf(net->name, IFNAMSIZ, "dvb%d%u%d",
			 dvbnet->dvbdev->adapter->num, dvbnet->dvbdev->id, if_num);
	else
		/* compatibility fix to keep dvb0_0 format */
		snprintf(net->name, IFNAMSIZ, "dvb%d_%d",
			 dvbnet->dvbdev->adapter->num, if_num);

	net->addr_len = 6;
	memcpy(net->dev_addr, dvbnet->dvbdev->adapter->proposed_mac, 6);

	dvbnet->device[if_num] = net;

	priv = netdev_priv(net);
	priv->net = net;
	priv->demux = dvbnet->demux;
	priv->pid = pid;
	priv->rx_mode = RX_MODE_UNI;
	priv->need_pusi = 1;
	priv->tscc = 0;
	priv->feedtype = feedtype;
	reset_ule(priv);

	INIT_WORK(&priv->set_multicast_list_wq, wq_set_multicast_list);
	INIT_WORK(&priv->restart_net_feed_wq, wq_restart_net_feed);
	mutex_init(&priv->mutex);

	net->base_addr = pid;

	if ((result = register_netdev(net)) < 0) {
		dvbnet->device[if_num] = NULL;
		free_netdev(net);
		return result;
	}
	pr_info("created network interface %s\n", net->name);

	return if_num;
}

static int dvb_net_remove_if(struct dvb_net *dvbnet, unsigned long num)
{
	struct net_device *net = dvbnet->device[num];
	struct dvb_net_priv *priv;

	if (!dvbnet->state[num])
		return -EINVAL;
	priv = netdev_priv(net);
	if (priv->in_use)
		return -EBUSY;

	dvb_net_stop(net);
	flush_work(&priv->set_multicast_list_wq);
	flush_work(&priv->restart_net_feed_wq);
	pr_info("removed network interface %s\n", net->name);
	unregister_netdev(net);
	dvbnet->state[num]=0;
	dvbnet->device[num] = NULL;
	free_netdev(net);

	return 0;
}

static int dvb_net_do_ioctl(struct file *file,
		  unsigned int cmd, void *parg)
{
	struct dvb_device *dvbdev = file->private_data;
	struct dvb_net *dvbnet = dvbdev->priv;
	int ret = 0;

	if (((file->f_flags&O_ACCMODE)==O_RDONLY))
		return -EPERM;

	if (mutex_lock_interruptible(&dvbnet->ioctl_mutex))
		return -ERESTARTSYS;

	switch (cmd) {
	case NET_ADD_IF:
	{
		struct dvb_net_if *dvbnetif = parg;
		int result;

		if (!capable(CAP_SYS_ADMIN)) {
			ret = -EPERM;
			goto ioctl_error;
		}

		if (!try_module_get(dvbdev->adapter->module)) {
			ret = -EPERM;
			goto ioctl_error;
		}

		result=dvb_net_add_if(dvbnet, dvbnetif->pid, dvbnetif->feedtype);
		if (result<0) {
			module_put(dvbdev->adapter->module);
			ret = result;
			goto ioctl_error;
		}
		dvbnetif->if_num=result;
		break;
	}
	case NET_GET_IF:
	{
		struct net_device *netdev;
		struct dvb_net_priv *priv_data;
		struct dvb_net_if *dvbnetif = parg;

		if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX ||
		    !dvbnet->state[dvbnetif->if_num]) {
			ret = -EINVAL;
			goto ioctl_error;
		}

		netdev = dvbnet->device[dvbnetif->if_num];

		priv_data = netdev_priv(netdev);
		dvbnetif->pid=priv_data->pid;
		dvbnetif->feedtype=priv_data->feedtype;
		break;
	}
	case NET_REMOVE_IF:
	{
		if (!capable(CAP_SYS_ADMIN)) {
			ret = -EPERM;
			goto ioctl_error;
		}
		if ((unsigned long) parg >= DVB_NET_DEVICES_MAX) {
			ret = -EINVAL;
			goto ioctl_error;
		}
		ret = dvb_net_remove_if(dvbnet, (unsigned long) parg);
		if (!ret)
			module_put(dvbdev->adapter->module);
		break;
	}

	/* binary compatibility cruft */
	case __NET_ADD_IF_OLD:
	{
		struct __dvb_net_if_old *dvbnetif = parg;
		int result;

		if (!capable(CAP_SYS_ADMIN)) {
			ret = -EPERM;
			goto ioctl_error;
		}

		if (!try_module_get(dvbdev->adapter->module)) {
			ret = -EPERM;
			goto ioctl_error;
		}

		result=dvb_net_add_if(dvbnet, dvbnetif->pid, DVB_NET_FEEDTYPE_MPE);
		if (result<0) {
			module_put(dvbdev->adapter->module);
			ret = result;
			goto ioctl_error;
		}
		dvbnetif->if_num=result;
		break;
	}
	case __NET_GET_IF_OLD:
	{
		struct net_device *netdev;
		struct dvb_net_priv *priv_data;
		struct __dvb_net_if_old *dvbnetif = parg;

		if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX ||
		    !dvbnet->state[dvbnetif->if_num]) {
			ret = -EINVAL;
			goto ioctl_error;
		}

		netdev = dvbnet->device[dvbnetif->if_num];

		priv_data = netdev_priv(netdev);
		dvbnetif->pid=priv_data->pid;
		break;
	}
	default:
		ret = -ENOTTY;
		break;
	}

ioctl_error:
	mutex_unlock(&dvbnet->ioctl_mutex);
	return ret;
}

static long dvb_net_ioctl(struct file *file,
	      unsigned int cmd, unsigned long arg)
{
	return dvb_usercopy(file, cmd, arg, dvb_net_do_ioctl);
}

static int dvb_net_close(struct inode *inode, struct file *file)
{
	struct dvb_device *dvbdev = file->private_data;
	struct dvb_net *dvbnet = dvbdev->priv;

	dvb_generic_release(inode, file);

	if(dvbdev->users == 1 && dvbnet->exit == 1)
		wake_up(&dvbdev->wait_queue);
	return 0;
}


static const struct file_operations dvb_net_fops = {
	.owner = THIS_MODULE,
	.unlocked_ioctl = dvb_net_ioctl,
	.open =	dvb_generic_open,
	.release = dvb_net_close,
	.llseek = noop_llseek,
};

static const struct dvb_device dvbdev_net = {
	.priv = NULL,
	.users = 1,
	.writers = 1,
#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
	.name = "dvb-net",
#endif
	.fops = &dvb_net_fops,
};

void dvb_net_release (struct dvb_net *dvbnet)
{
	int i;

	dvbnet->exit = 1;
	if (dvbnet->dvbdev->users < 1)
		wait_event(dvbnet->dvbdev->wait_queue,
				dvbnet->dvbdev->users==1);

	dvb_unregister_device(dvbnet->dvbdev);

	for (i=0; i<DVB_NET_DEVICES_MAX; i++) {
		if (!dvbnet->state[i])
			continue;
		dvb_net_remove_if(dvbnet, i);
	}
}
EXPORT_SYMBOL(dvb_net_release);


int dvb_net_init (struct dvb_adapter *adap, struct dvb_net *dvbnet,
		  struct dmx_demux *dmx)
{
	int i;

	mutex_init(&dvbnet->ioctl_mutex);
	dvbnet->demux = dmx;

	for (i=0; i<DVB_NET_DEVICES_MAX; i++)
		dvbnet->state[i] = 0;

	return dvb_register_device(adap, &dvbnet->dvbdev, &dvbdev_net,
			     dvbnet, DVB_DEVICE_NET, 0);
}
EXPORT_SYMBOL(dvb_net_init);
