summaryrefslogtreecommitdiff
path: root/linux/drivers/media/dvb/dvb-core
diff options
context:
space:
mode:
authorHolger Waechtler <devnull@localhost>2003-01-09 17:50:32 +0000
committerHolger Waechtler <devnull@localhost>2003-01-09 17:50:32 +0000
commitf470a7dcf7a0c2d011dd8e0225b7dc026efbf709 (patch)
treea3f8aecf94c9eab3429a7dad8bf0f07d09cb11cc /linux/drivers/media/dvb/dvb-core
parent6e2c952434138640f1dfa024fe69f545e81da43f (diff)
downloadmediapointer-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.c211
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_net.h23
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
+