Re: [zd1211-devs] multicast support and ipv6

2006-11-27 Thread Benoit PAPILLAULT
Uli Kunitz wrote:

 Benoit, I'm doing the filtering with following change:
OK. I read the patch a bit fast. My apologies...

 I'm absolutely interested in test results. The patch works for me  
 here under IPv4.

Patch is working under IPv6 as well. Thanks for the rewriting it.

Benoit

-
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT  business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.phpp=sourceforgeCID=DEVDEV
___
Zd1211-devs mailing list - http://zd1211.ath.cx/
Unsubscribe: https://lists.sourceforge.net/lists/listinfo/zd1211-devs


Re: [zd1211-devs] multicast support and ipv6

2006-11-26 Thread Ulrich Kunitz
On 06-11-23 22:52 Benoit PAPILLAULT wrote:

 Patch (replacing the previous) is attached.
 
 Best regards,
 Benoit

Benoit,

Thank's again for demonstrating how to solve the issue. I've
reworked your patch. You can find the new patch below. Please
check it with IPv6. I don't have here a running AP with IPv6
enabled. 

The patch is also include in my git tree.

http://www.deine-taler.de/zd1211/zd1211.git/

Please consider that the master branch compiles against 2.6.18 and
not 2.6.19. For 2.6.19 use the branch wireless-dev.

Regards,

Uli

Support for multicast adresses is implemented by supporting the
set_multicast_list() function of the network device. Address
filtering is supported by a group hash table in the device. Should
fix bugzilla.kernel.org bug 7424.

Signed-off-by: Ulrich Kunitz [EMAIL PROTECTED]
---
 zd_chip.c   |   13 +
 zd_chip.h   |   43 ++-
 zd_mac.c|   44 +++-
 zd_mac.h|3 +++
 zd_netdev.c |2 +-
 5 files changed, 102 insertions(+), 3 deletions(-)

diff --git a/zd_chip.c b/zd_chip.c
index bfff84c..4624379 100644
--- a/zd_chip.c
+++ b/zd_chip.c
@@ -1672,3 +1672,16 @@ int zd_rfwritev_cr_locked(struct zd_chip
 
return 0;
 }
+
+int zd_chip_set_multicast_hash(struct zd_chip *chip,
+  struct zd_mc_hash *hash)
+{
+   struct zd_ioreq32 ioreqs[] = {
+   { CR_GROUP_HASH_P1, hash-low },
+   { CR_GROUP_HASH_P2, hash-high },
+   };
+
+   dev_dbg_f(zd_chip_dev(chip), hash l 0x%08x h 0x%08x\n,
+   ioreqs[0].value, ioreqs[1].value);
+   return zd_iowrite32a(chip, ioreqs, ARRAY_SIZE(ioreqs));
+}
diff --git a/zd_chip.h b/zd_chip.h
index 0df9d5b..6ed3fb6 100644
--- a/zd_chip.h
+++ b/zd_chip.h
@@ -395,10 +395,19 @@ #define CR_MAC_ADDR_P2CTL_REG(0x0614)
 #define CR_BSSID_P1CTL_REG(0x0618)
 #define CR_BSSID_P2CTL_REG(0x061C)
 #define CR_BCN_PLCP_CFGCTL_REG(0x0620)
+
+/* Group hash table for filtering incoming packets.
+ *
+ * The group hash table is 64 bit large and split over two parts. The first
+ * part is the lower part. The upper 6 bits of the last byte of the target
+ * address are used as index. Packets are received if the hash table bit is
+ * set. This is used for multicast handling, but for broadcasts (address
+ * ff:ff:ff:ff:ff:ff) the highest bit in the second table must also be set.
+ */
 #define CR_GROUP_HASH_P1   CTL_REG(0x0624)
 #define CR_GROUP_HASH_P2   CTL_REG(0x0628)
-#define CR_RX_TIMEOUT  CTL_REG(0x062C)
 
+#define CR_RX_TIMEOUT  CTL_REG(0x062C)
 /* Basic rates supported by the BSS. When producing ACK or CTS messages, the
  * device will use a rate in this table that is less than or equal to the rate
  * of the incoming frame which prompted the response */
@@ -850,4 +859,36 @@ int zd_chip_handle_signal_strength(struc
 
 u16 zd_rx_rate(const void *rx_frame, const struct rx_status *status);
 
+struct zd_mc_hash {
+   u32 low;
+   u32 high;
+};
+
+static inline void zd_mc_clear(struct zd_mc_hash *hash)
+{
+   hash-low = 0;
+   /* The interfaces must always received broadcasts.
+* The hash of the broadcast address ff:ff:ff:ff:ff:ff is 63.
+*/
+   hash-high = 0x8000;
+}
+
+static inline void zd_mc_add_all(struct zd_mc_hash *hash)
+{
+   hash-low = hash-high = 0x;
+}
+
+static inline void zd_mc_add_addr(struct zd_mc_hash *hash, u8 *addr)
+{
+   unsigned int i = addr[5]  2;
+   if (i  32) {
+   hash-low |= 1  i;
+   } else {
+   hash-high |= 1  (i-32);
+   }
+}
+
+int zd_chip_set_multicast_hash(struct zd_chip *chip,
+  struct zd_mc_hash *hash);
+
 #endif /* _ZD_CHIP_H */
diff --git a/zd_mac.c b/zd_mac.c
index 30ae0c2..5b100a3 100644
--- a/zd_mac.c
+++ b/zd_mac.c
@@ -37,6 +37,8 @@ static void housekeeping_init(struct zd_
 static void housekeeping_enable(struct zd_mac *mac);
 static void housekeeping_disable(struct zd_mac *mac);
 
+static void set_multicast_hash_handler(void *mac_ptr);
+
 int zd_mac_init(struct zd_mac *mac,
struct net_device *netdev,
struct usb_interface *intf)
@@ -51,6 +53,8 @@ int zd_mac_init(struct zd_mac *mac,
softmac_init(ieee80211_priv(netdev));
zd_chip_init(mac-chip, netdev, intf);
housekeeping_init(mac);
+   INIT_WORK(mac-set_multicast_hash_work, set_multicast_hash_handler,
+ mac);
return 0;
 }
 
@@ -132,6 +136,7 @@ out:
 
 void zd_mac_clear(struct zd_mac *mac)
 {
+   flush_workqueue(zd_workqueue);
zd_chip_clear(mac-chip);
ZD_ASSERT(!spin_is_locked(mac-lock));
ZD_MEMCLEAR(mac, sizeof(struct zd_mac));
@@ -245,6 +250,42 @@ int zd_mac_set_mac_address(struct net_de
return 0;
 }
 
+static void 

Re: [zd1211-devs] multicast support and ipv6

2006-11-26 Thread Uli Kunitz
 IPv6 needs to ignore packets sent, which is not done in your patch.
 However, I think such filtering is not zd1211 specific and could be
 better done in the generic softmac layer. What is the process to patch
 the softmac layer? I was also wondering if filtering ALL packets whose
 sender mac is our MAC would be more appropriate? (currently, my patch
 only filters out multicast packets with sender MAC being our MAC).

Benoit, I'm doing the filtering with following change:

  @@ -771,7 +812,8 @@ static int is_data_packet_for_us(struct
  }

  return memcmp(hdr-addr1, netdev-dev_addr, ETH_ALEN) == 0 ||
-   is_multicast_ether_addr(hdr-addr1) ||
+   (is_multicast_ether_addr(hdr-addr1) 
+memcmp(hdr-addr3, netdev-dev_addr, ETH_ALEN) != 0) ||
 (netdev-flags  IFF_PROMISC);
  }

It's exactly as you are doing, but will work also in other modes.
According to RFC2462 there are problems with removing frames
with the identical source address. So limiting it has some value.
One could implement something more complex like
updating a time-stamp variable in tx for multicast packets. And suppress
the incoming packet only if it is in a certain timw window after the tx.
I doubt that it is worth to do it.

Sharing the code with other cards, might not be possible, because the  
devices
might behave differently. For instance doing the filtering on its own.

I'm absolutely interested in test results. The patch works for me  
here under IPv4.

Cheers,

Uli
--
Uli Kunitz




-
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT  business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.phpp=sourceforgeCID=DEVDEV
___
Zd1211-devs mailing list - http://zd1211.ath.cx/
Unsubscribe: https://lists.sourceforge.net/lists/listinfo/zd1211-devs


Re: [zd1211-devs] multicast support and ipv6

2006-11-23 Thread Benoit PAPILLAULT

Benoit PAPILLAULT wrote:

Hello,

I noticed that the zd1211rw driver does not work with ipv6 since the 
autoconfiguration process requires multicast to be implemented. This was 
working with the vendor driver. I successfully ported the needed part of 
the source code to zd1211rw to add multicast support (in fact, the cards 
needs to be instruct with the proper MAC multicast addr in order to 
receive the packets intended to those multicast addr). It works (patch 
attached, against git repository from dsd).


However, ipv6 is still not working and i got several messages wlan0: 
duplicate address detected!. I'm not sure yet but i think that 
multicast packets sent from STA to AP are then retransmitted by the AP 
to all STA, including the STA which has sent it!


How to make ipv6 working?

Best regards,
Benoit


I found it. Broadcast/multicast packets sent by the AP are retransmitted 
by the AP and as such, received by the STA. Reading the vendor driver 
and the 802.11 specs, I added a filter against broadcast/multicast 
packets whose source address (SA) is ours.


IPv6 is now working!

Patch (replacing the previous) is attached.

Best regards,
Benoit

diff --git a/zd_chip.c b/zd_chip.c
diff --git a/zd_def.h b/zd_def.h
diff --git a/zd_mac.c b/zd_mac.c
index 8acd168..fac9d65 100644
--- a/zd_mac.c
+++ b/zd_mac.c
@@ -36,6 +36,9 @@ static void softmac_init(struct ieee8021
 static void housekeeping_init(struct zd_mac *mac);
 static void housekeeping_enable(struct zd_mac *mac);
 static void housekeeping_disable(struct zd_mac *mac);
+static void zd_mac_kevent(void *);
+
+#define KEVENT_SET_MULTICAST 1
 
 int zd_mac_init(struct zd_mac *mac,
 	struct net_device *netdev,
@@ -51,6 +54,9 @@ int zd_mac_init(struct zd_mac *mac,
 	softmac_init(ieee80211_priv(netdev));
 	zd_chip_init(mac-chip, netdev, intf);
 	housekeeping_init(mac);
+
+INIT_WORK(mac-kevent, zd_mac_kevent, netdev);
+mac-kevent_flags = 0;
 	return 0;
 }
 
@@ -220,6 +226,85 @@ int zd_mac_stop(struct net_device *netde
 	return 0;
 }
 
+/*
+  Set the proper registers from the list of multicast addr. to listen to.
+  Promiscuous and allmulti modes are handled here as well. This function cannot
+  be called in atomic context since zd_io... function needs to sleep.
+*/
+
+void zd_mac_set_multicast_list_real(struct net_device * dev)
+{
+struct zd_mac * mac = zd_netdev_mac(dev);
+struct zd_chip * chip = mac-chip;
+struct dev_mc_list * mc_list;
+unsigned int i;
+u32 tmp;
+
+/* check that the interface is UP */
+if (!(dev-flags  IFF_UP))
+return;
+
+zd_iowrite32(chip, CR_GROUP_HASH_P1, 0);
+zd_iowrite32(chip, CR_GROUP_HASH_P2, 0x8000);
+
+for (i=0, mc_list=dev-mc_list;
+ idev-mc_count; i++, mc_list = mc_list-next) {
+
+u8 val;
+
+printk(__FILE__  : multicast  MAC_FMT \n,
+   MAC_ARG(mc_list-dmi_addr));
+
+val = mc_list-dmi_addr[5]  2;
+if (val  32) {
+zd_ioread32(chip, CR_GROUP_HASH_P1, tmp);
+tmp |= 1  val;
+zd_iowrite32(chip, CR_GROUP_HASH_P1, tmp);
+} else {
+val -= 32;
+zd_ioread32(chip, CR_GROUP_HASH_P2, tmp);
+tmp |= 1  val;
+zd_iowrite32(chip, CR_GROUP_HASH_P2, tmp);
+}
+}
+
+if ((dev-flags  IFF_PROMISC) ||
+(dev-flags  IFF_ALLMULTI)) {
+zd_iowrite32(chip, CR_GROUP_HASH_P1, 0x);
+zd_iowrite32(chip, CR_GROUP_HASH_P2, 0x);
+}
+
+zd_ioread32(chip, CR_GROUP_HASH_P1, tmp);
+printk(__FILE__  : GroupHashP1 = %x\n, tmp);
+zd_ioread32(chip, CR_GROUP_HASH_P2, tmp);
+printk(__FILE__  : GroupHashP2 = %x\n, tmp);
+}
+
+/*
+  This is the function called by the netdev layer. This function is in an
+  atomic context and such registers cannot be set directly. As such, the work
+  is defered to the default workqueue, which will call zd_mac_keven().
+*/
+
+void zd_mac_set_multicast_list(struct net_device * dev)
+{
+struct zd_mac * mac = zd_netdev_mac(dev);
+
+set_bit(KEVENT_SET_MULTICAST, mac-kevent_flags);
+schedule_work(mac-kevent);
+}
+
+void zd_mac_kevent(void * data)
+{
+struct net_device * dev = (struct net_device *) data;
+struct zd_mac * mac = zd_netdev_mac(dev);
+
+if (test_bit(KEVENT_SET_MULTICAST, mac-kevent_flags)) {
+zd_mac_set_multicast_list_real(dev);
+clear_bit(KEVENT_SET_MULTICAST, mac-kevent_flags);
+}
+}
+
 int zd_mac_set_mac_address(struct net_device *netdev, void *p)
 {
 	int r;
@@ -771,6 +856,14 @@ static int is_data_packet_for_us(struct
 		IEEE80211_FCTL_FROMDS ||
 		memcmp(hdr-addr2, ieee-bssid, ETH_ALEN) != 0)
 			return 0;
+
+/* broadcast or multicast packets are resent by the AP, so we
+   ignore packets we sent */
+
+if (is_multicast_ether_addr(hdr-addr1)  
+(memcmp(hdr-addr3, netdev-dev_addr, ETH_ALEN) == 0)) {
+return 0;
+ 

Re: [zd1211-devs] multicast support and ipv6

2006-11-23 Thread Uli Kunitz

Benoit,

I just send my mail and received then yours.

I will rework your patch as outlined in my e-mail at the weekend.
Then it will be in my master branch for 2.6.18 and in the wireless- 
dev for 2.6.19-rc*.


Both trees are synchronized with Daniel's tree. Daniel forwards  
usually the patches

to the John Linville, the maintainer of the wireless tree.

Kind regards,

UIi

--
Uli Kunitz



-
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT  business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.phpp=sourceforgeCID=DEVDEV___
Zd1211-devs mailing list - http://zd1211.ath.cx/
Unsubscribe: https://lists.sourceforge.net/lists/listinfo/zd1211-devs