diff options
author | Holger Waechtler <devnull@localhost> | 2003-01-09 17:50:32 +0000 |
---|---|---|
committer | Holger Waechtler <devnull@localhost> | 2003-01-09 17:50:32 +0000 |
commit | f470a7dcf7a0c2d011dd8e0225b7dc026efbf709 (patch) | |
tree | a3f8aecf94c9eab3429a7dad8bf0f07d09cb11cc /linux/drivers/media/dvb/dvb-core | |
parent | 6e2c952434138640f1dfa024fe69f545e81da43f (diff) | |
download | mediapointer-dvb-s2-f470a7dcf7a0c2d011dd8e0225b7dc026efbf709.tar.gz mediapointer-dvb-s2-f470a7dcf7a0c2d011dd8e0225b7dc026efbf709.tar.bz2 |
take over Bugfixes and improvements by Ralph Metzler <rjkm@metzlerbros.org>
Diffstat (limited to 'linux/drivers/media/dvb/dvb-core')
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/dvb_net.c | 211 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/dvb_net.h | 23 |
2 files changed, 132 insertions, 102 deletions
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_net.c b/linux/drivers/media/dvb/dvb-core/dvb_net.c index d3dd7806d..8d2c9e5e1 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_net.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_net.c @@ -3,28 +3,49 @@ * * Copyright (C) 2001 Convergence integrated media GmbH * Ralph Metzler <ralph@convergence.de> + * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de> * * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 + * 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 Lesser General Public License + * 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. - * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * Or, point your browser to http://www.gnu.org/copyleft/gpl.html + * */ -#include <linux/dvb/net.h> - #include <asm/uaccess.h> -#include "demux.h" + +#include <linux/dvb/net.h> +#include "dvb_demux.h" #include "dvb_net.h" +#include "compat.h" + + +#define DVB_NET_MULTICAST_MAX 10 + +struct dvb_net_priv { + struct net_device_stats stats; + char name[6]; + u16 pid; + struct dmx_demux_s *demux; + dmx_section_feed_t *secfeed; + dmx_section_filter_t *secfilter; + int multi_num; + dmx_section_filter_t *multi_secfilter[DVB_NET_MULTICAST_MAX]; + unsigned char multi_macs[DVB_NET_MULTICAST_MAX][6]; + int mode; +}; /* * Determine the packet's protocol ID. The rule here is that we @@ -73,7 +94,7 @@ unsigned short my_eth_type_trans(struct sk_buff *skb, struct net_device *dev) } static void -dvb_net_sec(struct net_device *dev, const u8 *pkt, int pkt_len) +dvb_net_sec(struct net_device *dev, u8 *pkt, int pkt_len) { u8 *eth; struct sk_buff *skb; @@ -86,7 +107,7 @@ dvb_net_sec(struct net_device *dev, const u8 *pkt, int pkt_len) if (skb == NULL) { printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name); - ((dvb_net_priv_t *)dev->priv)->stats.rx_dropped++; + ((struct dvb_net_priv *)dev->priv)->stats.rx_dropped++; return; } eth=(u8 *) skb_put(skb, pkt_len+2); @@ -104,15 +125,14 @@ dvb_net_sec(struct net_device *dev, const u8 *pkt, int pkt_len) skb->protocol=my_eth_type_trans(skb,dev); skb->dev=dev; - ((dvb_net_priv_t *)dev->priv)->stats.rx_packets++; - ((dvb_net_priv_t *)dev->priv)->stats.rx_bytes+=skb->len; - //sti(); + ((struct dvb_net_priv *)dev->priv)->stats.rx_packets++; + ((struct dvb_net_priv *)dev->priv)->stats.rx_bytes+=skb->len; netif_rx(skb); } static int -dvb_net_callback(const u8 *buffer1, size_t buffer1_len, - const u8 *buffer2, size_t buffer2_len, +dvb_net_callback(u8 *buffer1, size_t buffer1_len, + u8 *buffer2, size_t buffer2_len, dmx_section_filter_t *filter, dmx_success_t success) { @@ -130,18 +150,21 @@ dvb_net_tx(struct sk_buff *skb, struct net_device *dev) return 0; } -#define MASK 0x00; +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_set(struct net_device *dev, dmx_section_filter_t **secfilter, - unsigned char *mac) + u8 *mac, u8 *mac_mask) { - dvb_net_priv_t *priv=(dvb_net_priv_t *)dev->priv; + struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv; int ret; *secfilter=0; - ret=priv->secfeed->allocate_filter(priv->secfeed, secfilter); + ret = priv->secfeed->allocate_filter(priv->secfeed, secfilter); if (ret<0) { printk("%s: could not get filter\n", dev->name); return ret; @@ -149,25 +172,26 @@ dvb_net_filter_set(struct net_device *dev, (*secfilter)->priv=(void *) dev; - memset((*secfilter)->filter_value, 0, DMX_MAX_FILTER_SIZE); - memset((*secfilter)->filter_mask , 0, DMX_MAX_FILTER_SIZE); + 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_mask[0]=MASK; + (*secfilter)->filter_mask[0]=0xff; (*secfilter)->filter_value[3]=mac[5]; - (*secfilter)->filter_mask[3]=MASK; + (*secfilter)->filter_mask[3]=mac_mask[5]; (*secfilter)->filter_value[4]=mac[4]; - (*secfilter)->filter_mask[4]=MASK; + (*secfilter)->filter_mask[4]=mac_mask[4]; (*secfilter)->filter_value[8]=mac[3]; - (*secfilter)->filter_mask[8]=MASK; + (*secfilter)->filter_mask[8]=mac_mask[3]; (*secfilter)->filter_value[9]=mac[2]; - (*secfilter)->filter_mask[9]=MASK; + (*secfilter)->filter_mask[9]=mac_mask[2]; (*secfilter)->filter_value[10]=mac[1]; - (*secfilter)->filter_mask[10]=MASK; + (*secfilter)->filter_mask[10]=mac_mask[1]; (*secfilter)->filter_value[11]=mac[0]; - (*secfilter)->filter_mask[11]=MASK; + (*secfilter)->filter_mask[11]=mac_mask[0]; printk("%s: filter mac=%02x %02x %02x %02x %02x %02x\n", dev->name, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); @@ -178,15 +202,15 @@ static int dvb_net_feed_start(struct net_device *dev) { int ret, i; - dvb_net_priv_t *priv=(dvb_net_priv_t *)dev->priv; - dmx_demux_t *demux=priv->demux; - unsigned char *mac=(unsigned char *) dev->dev_addr; + struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv; + dmx_demux_t *demux = priv->demux; + unsigned char *mac = (unsigned char *) dev->dev_addr; priv->secfeed=0; priv->secfilter=0; - ret = demux->allocate_section_feed (demux, &priv->secfeed, - dvb_net_callback); + ret=demux->allocate_section_feed(demux, &priv->secfeed, + dvb_net_callback); if (ret<0) { printk("%s: could not get section feed\n", dev->name); return ret; @@ -202,26 +226,38 @@ dvb_net_feed_start(struct net_device *dev) } MOD_INC_USE_COUNT; - dvb_net_filter_set(dev, &priv->secfilter, mac); - for (i=0; i<priv->multi_num; i++) - dvb_net_filter_set(dev, &priv->secfilter, - priv->multi_macs[i]); + if (priv->mode<3) + dvb_net_filter_set(dev, &priv->secfilter, mac, mask_normal); + switch (priv->mode) { + case 1: + for (i=0; i<priv->multi_num; i++) + dvb_net_filter_set(dev, &priv->multi_secfilter[i], + priv->multi_macs[i], mask_normal); + break; + case 2: + priv->multi_num=1; + dvb_net_filter_set(dev, &priv->multi_secfilter[0], mac_allmulti, mask_allmulti); + break; + case 3: + priv->multi_num=0; + dvb_net_filter_set(dev, &priv->secfilter, mac, mask_promisc); + break; + } + priv->secfeed->start_filtering(priv->secfeed); - printk("%s: feed_started\n", dev->name); return 0; } static void dvb_net_feed_stop(struct net_device *dev) { - dvb_net_priv_t *priv=(dvb_net_priv_t *)dev->priv; + struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv; int i; if (priv->secfeed) { if (priv->secfeed->is_filtering) priv->secfeed->stop_filtering(priv->secfeed); - printk("%s: feed_stopped\n", dev->name); if (priv->secfilter) priv->secfeed-> release_filter(priv->secfeed, @@ -246,20 +282,11 @@ dvb_net_feed_stop(struct net_device *dev) static int dvb_set_mc_filter(struct net_device *dev, struct dev_mc_list *mc) { - dvb_net_priv_t *priv=(dvb_net_priv_t *)dev->priv; + struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv; if (priv->multi_num==DVB_NET_MULTICAST_MAX) return -ENOMEM; - printk("%s: set_mc_filter %d: %02x %02x %02x %02x %02x %02x\n", - dev->name, - priv->multi_num, - mc->dmi_addr[0], - mc->dmi_addr[1], - mc->dmi_addr[2], - mc->dmi_addr[3], - mc->dmi_addr[4], - mc->dmi_addr[5]); memcpy(priv->multi_macs[priv->multi_num], mc->dmi_addr, 6); priv->multi_num++; @@ -269,23 +296,24 @@ dvb_set_mc_filter(struct net_device *dev, struct dev_mc_list *mc) static void dvb_net_set_multi(struct net_device *dev) { - dvb_net_priv_t *priv=(dvb_net_priv_t *)dev->priv; + struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv; - printk("%s: set_multi()\n", dev->name); dvb_net_feed_stop(dev); + priv->mode=0; if (dev->flags&IFF_PROMISC) { - /* Enable promiscuous mode */ printk("%s: promiscuous mode\n", dev->name); + priv->mode=3; } else if((dev->flags&IFF_ALLMULTI)) { - /* Disable promiscuous mode, use normal mode. */ - printk("%s: normal mode\n", dev->name); + printk("%s: allmulti mode\n", dev->name); + priv->mode=2; } else if(dev->mc_count) { int mci; struct dev_mc_list *mc; printk("%s: set_mc_list, %d entries\n", dev->name, dev->mc_count); + priv->mode=1; priv->multi_num=0; for (mci=0, mc=dev->mc_list; mci<dev->mc_count; @@ -335,15 +363,13 @@ dvb_net_stop(struct net_device *dev) static struct net_device_stats * dvb_net_get_stats(struct net_device *dev) { - return &((dvb_net_priv_t *)dev->priv)->stats; + return &((struct dvb_net_priv*) dev->priv)->stats; } static int dvb_net_init_dev(struct net_device *dev) { - printk("dvb_net: dvb_net_init_dev()\n"); - ether_setup(dev); dev->open = dvb_net_open; @@ -354,6 +380,7 @@ dvb_net_init_dev(struct net_device *dev) dev->set_config = dvb_net_set_config; dev->set_mac_address = dvb_net_set_mac; dev->mtu = 4096; + dev->mc_count = 0; dev->flags |= IFF_NOARP; dev->hard_header_cache = NULL; @@ -364,7 +391,7 @@ dvb_net_init_dev(struct net_device *dev) } static int -get_if(dvb_net_t *dvbnet) +get_if(struct dvb_net *dvbnet) { int i; @@ -379,10 +406,11 @@ get_if(dvb_net_t *dvbnet) int -dvb_net_add_if(dvb_net_t *dvbnet, u16 pid) +dvb_net_add_if(struct dvb_net *dvbnet, u16 pid) { struct net_device *net; dmx_demux_t *demux; + struct dvb_net_priv *priv; int result; int if_num; @@ -402,15 +430,17 @@ dvb_net_add_if(dvb_net_t *dvbnet, u16 pid) net->name[5]=if_num+0x30; net->next = NULL; net->init = dvb_net_init_dev; - net->priv = kmalloc(sizeof(dvb_net_priv_t), GFP_KERNEL); + net->priv = kmalloc(sizeof(struct dvb_net_priv), GFP_KERNEL); if (net->priv == NULL) return -ENOMEM; - memset(net->priv, 0, sizeof(dvb_net_priv_t)); - ((dvb_net_priv_t *)net->priv)->demux=demux; - ((dvb_net_priv_t *)net->priv)->pid=pid; + priv = net->priv; + memset(priv, 0, sizeof(struct dvb_net_priv)); + priv->demux = demux; + priv->pid = pid; + priv->mode = 0; - net->base_addr=pid; + net->base_addr = pid; if ((result = register_netdev(net)) < 0) { return result; @@ -420,7 +450,7 @@ dvb_net_add_if(dvb_net_t *dvbnet, u16 pid) } int -dvb_net_remove_if(dvb_net_t *dvbnet, int num) +dvb_net_remove_if(struct dvb_net *dvbnet, int num) { if (!dvbnet->state[num]) return -EINVAL; @@ -432,11 +462,11 @@ dvb_net_remove_if(dvb_net_t *dvbnet, int num) return 0; } -int dvb_net_ioctl(struct inode *inode, struct file *file, +int dvb_net_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *parg) { - struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; - dvb_net_t *dvbnet=(dvb_net_t *) dvbdev->priv; + struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; + struct dvb_net *dvbnet = (struct dvb_net *) dvbdev->priv; if (((file->f_flags&O_ACCMODE)==O_RDONLY)) return -EPERM; @@ -461,23 +491,32 @@ int dvb_net_ioctl(struct inode *inode, struct file *file, return 0; } +static int +dvb_net_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + return dvb_usercopy(inode, file, cmd, arg, dvb_net_do_ioctl); +} + static struct file_operations dvb_net_fops = { - .owner = THIS_MODULE, - .ioctl = dvb_generic_ioctl, - .open = dvb_generic_open, - .release = dvb_generic_release, + .owner = THIS_MODULE, + .read = 0, + .write = 0, + .ioctl = dvb_net_ioctl, + .open = dvb_generic_open, + .release = dvb_generic_release, + .poll = 0, }; static struct dvb_device dvbdev_net = { - .priv = 0, - .users = 1, - .writers = 1, - .fops = &dvb_net_fops, - .kernel_ioctl = dvb_net_ioctl, + .priv = 0, + .users = 1, + .writers = 1, + .fops = &dvb_net_fops, }; void -dvb_net_release(dvb_net_t *dvbnet) +dvb_net_release(struct dvb_net *dvbnet) { int i; @@ -490,15 +529,19 @@ dvb_net_release(dvb_net_t *dvbnet) } int -dvb_net_init(struct dvb_adapter *adap, dvb_net_t *dvbnet, dmx_demux_t *demux) +dvb_net_init(struct dvb_adapter *adap, struct dvb_net *dvbnet, dmx_demux_t *dmx) { int i; - dvbnet->demux=demux; - dvbnet->dev_num=DVB_NET_DEVICES_MAX; + dvbnet->demux = dmx; + dvbnet->dev_num = DVB_NET_DEVICES_MAX; + for (i=0; i<dvbnet->dev_num; i++) - dvbnet->state[i]=0; - dvb_register_device(adap, &dvbnet->dvbdev, &dvbdev_net, dvbnet, DVB_DEVICE_NET); + dvbnet->state[i] = 0; + + dvb_register_device (adap, &dvbnet->dvbdev, &dvbdev_net, + dvbnet, DVB_DEVICE_NET); + return 0; } diff --git a/linux/drivers/media/dvb/dvb-core/dvb_net.h b/linux/drivers/media/dvb/dvb-core/dvb_net.h index 16d270356..1813b2298 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_net.h +++ b/linux/drivers/media/dvb/dvb-core/dvb_net.h @@ -32,23 +32,9 @@ #include "dvbdev.h" #define DVB_NET_DEVICES_MAX 10 -#define DVB_NET_MULTICAST_MAX 10 - -typedef struct dvb_net_priv_s { - struct net_device_stats stats; - char name[6]; - u16 pid; - dmx_demux_t *demux; - dmx_section_feed_t *secfeed; - dmx_section_filter_t *secfilter; - int multi_num; - dmx_section_filter_t *multi_secfilter[DVB_NET_MULTICAST_MAX]; - unsigned char multi_macs[DVB_NET_MULTICAST_MAX][6]; -} dvb_net_priv_t; - -typedef struct dvb_net_s { - struct dvb_device *dvbdev; +typedef struct dvb_net { + struct dvb_device *dvbdev; int card_num; int dev_num; struct net_device device[DVB_NET_DEVICES_MAX]; @@ -57,7 +43,8 @@ typedef struct dvb_net_s { } dvb_net_t; -void dvb_net_release(dvb_net_t *); -int dvb_net_init(struct dvb_adapter *, dvb_net_t *, dmx_demux_t *); +void dvb_net_release(struct dvb_net *); +int dvb_net_init(struct dvb_adapter *, struct dvb_net *, dmx_demux_t *); #endif + |