[haiku-development] if_bge for Haiku

  • From: Pieter Panman <pieter@xxxxxxxxx>
  • To: haiku-development@xxxxxxxxxxxxx
  • Date: Sun, 28 Sep 2008 21:23:55 +0200

Hey Haiku Developers,

I got tired of not having any networking for my laptop with Haiku, so I decided to work on the FreeBDS if_bge driver that Axel has added to the repository, under the name broadcom_bcm570x. My laptop has the Broadcom 5787 mobile chip.

I managed to get it to compile (with some cheats), but it does not work quite yet. See the attached diff for what I did to make it compile. I still have to implement m_cljget, but I get stuck on other things first. Besides, if it is called, it will panic, then I'll implement it :) It's something to do with jumbo frames.

When I start Haiku with the driver added to the image, it gets to the red rocket, where things go haywire. (without this driver it boots fine) See these pictures of the debugging output: it is very exciting to at least see it is identifying my device and initializing it.
http://www.panman.eu/haiku/if_bge1.jpg
http://www.panman.eu/haiku/if_bge2.jpg
http://www.panman.eu/haiku/if_bge3.jpg

My suspicion is that I'm messing up the interrupts, because everything else is rather bothered by my driver's actions. I have very little driver writing experience, so this is mostly trial and error for me.

I also tried these two below, but that doesn't help at all. Probably this device generates interrupts, and this does not apply.
NO_HAIKU_CHECK_DISABLE_INTERRUPTS();
NO_HAIKU_REENABLE_INTERRUPTS();

I also tried with the latest driver from http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/dev/bge/ but they now added m_collapse, which still needs to be added to the layer. So I figured I'd focus on the current driver, can always update later.

Any advise would be greatly appreciated. I will also add this information to the ticket. http://dev.haiku-os.org/ticket/1590

Regards,
Pieter
Index: add-ons/kernel/drivers/network/broadcom_bcm570x/dev/bge/glue.c
===================================================================
--- add-ons/kernel/drivers/network/broadcom_bcm570x/dev/bge/glue.c      
(revision 27764)
+++ add-ons/kernel/drivers/network/broadcom_bcm570x/dev/bge/glue.c      
(working copy)
@@ -5,6 +5,7 @@
 
 
 #include <sys/bus.h>
+#include "if_bgereg.h"
 
 
 HAIKU_FBSD_DRIVER_GLUE(broadcom_bcm570x, bge, pci);
@@ -25,3 +26,26 @@
        return __haiku_probe_miibus(dev, drivers);
 }
 
+int
+__haiku_disable_interrupts(device_t dev)
+{
+       // Honestly, I don't know if this is correct. 
+       // I just copied it from if_bge searching for disable interrupts
+       struct bge_softc *sc = device_get_softc(dev);
+       BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR);
+       CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 1);
+
+       // TODO: should we check if this succeeded and return appropriately?
+       return 1;
+}
+
+
+void
+__haiku_reenable_interrupts(device_t dev)
+{
+       // Honestly, I don't know if this is correct. 
+       // I just copied it from if_bge searching for enable interrupts
+       struct bge_softc *sc = device_get_softc(dev);
+       BGE_CLRBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR);
+       CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 0);
+}
Index: libs/compat/freebsd_network/compat/sys/mbuf.h
===================================================================
--- libs/compat/freebsd_network/compat/sys/mbuf.h       (revision 27764)
+++ libs/compat/freebsd_network/compat/sys/mbuf.h       (working copy)
@@ -82,6 +82,9 @@
 
 #define M_BCAST                        0x00000200
 #define M_MCAST                        0x00000400
+#define        M_FRAG                  0x00000800
+#define        M_FIRSTFRAG             0x00001000
+#define        M_LASTFRAG              0x00002000
 #define        M_VLANTAG               0x00010000
 
 #define CSUM_IP                        0x0001
@@ -124,6 +127,7 @@
 struct mbuf *m_get(int how, short type);
 struct mbuf *m_gethdr(int how, short type);
 void m_clget(struct mbuf *m, int how);
+void * m_cljget(struct mbuf *m, int how, int size);
 
 void m_extadd(struct mbuf *m, caddr_t buffer, u_int size,
     void (*freeHook)(void *, void *), void *args, int flags, int type);
Index: libs/compat/freebsd_network/mbuf.c
===================================================================
--- libs/compat/freebsd_network/mbuf.c  (revision 27764)
+++ libs/compat/freebsd_network/mbuf.c  (working copy)
@@ -150,7 +150,36 @@
        construct_ext_mbuf(m, how);
 }
 
+/*
+ * Comment from the freebsd (mbuf.h):
+ * m_cljget() is different from m_clget() as it can allocate clusters without
+ * attaching them to an mbuf.  In that case the return value is the pointer
+ * to the cluster of the requested size.  If an mbuf was specified, it gets
+ * the cluster attached to it and the return value can be safely ignored.
+ * For size it takes MCLBYTES, MJUMPAGESIZE, MJUM9BYTES, MJUM16BYTES.
+ */
+void *
+m_cljget(struct mbuf *m, int how, int size)
+{
+       // TODO: implement this
+       panic("m_cljget not yet implemented");
+       return (void *) NULL;
 
+/*
+//     This is the freebsd code
+       uma_zone_t zone;
+
+       if (m && m->m_flags & M_EXT)
+               printf("%s: %p mbuf already has cluster\n", __func__, m);
+       if (m != NULL)
+               m->m_ext.ext_buf = NULL;
+
+       zone = m_getzone(size);
+       return (uma_zalloc_arg(zone, m, how));
+*/
+}
+
+
 void
 m_freem(struct mbuf *mb)
 {

Other related posts: