changeset 76:51bea596df7f

Start a patch for the Rx init
author Louis Opter <louis@lse.epitech.net>
date Sun, 04 Mar 2012 15:27:34 +0100
parents c076a41a753c
children 892b3bc7e43b
files e1000_initialize_reception.patch series
diffstat 2 files changed, 112 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/e1000_initialize_reception.patch	Sun Mar 04 15:27:34 2012 +0100
@@ -0,0 +1,111 @@
+# HG changeset patch
+# Parent 40e5b7402e64e301b898fa4da1056a5348522fbb
+rathaxes: initialize reception on the e1000 sample:
+
+- This is documented in details in the sections 14.4 and 3.2 of the
+  Intel Gigabit Controller Software Developer manual;
+- "Address filtering" is set up, address filters just tell the hardware
+  which packets they should accept (unicast/multicast/vlan/promisc), we
+  simply configure the hardware to accept packet for its own mac
+  address (receive address);
+- It involves setting up a ring of receive descriptors (their format is
+  documented in section 3.2.3) and an internal data structure to keep
+  track of the ring;
+- Each descriptor of the ring correspond to an skbuff (skbuff are
+  allocated individually).
+
+diff --git a/rathaxes/samples/e1000/e1000.blt b/rathaxes/samples/e1000/e1000.blt
+--- a/rathaxes/samples/e1000/e1000.blt
++++ b/rathaxes/samples/e1000/e1000.blt
+@@ -36,6 +36,25 @@
+         }
+     }
+ 
++    template type   e1000::RingRx()
++    {
++        chunk   LKM::includes()
++        {
++        }
++
++        chunk   ::decl()
++        {
++        }
++
++        chunk   ::init()
++        {
++        }
++
++        map
++        {
++        }
++    }
++
+     template type   e1000::Register()
+     {
+         chunk   LKM::includes()
+@@ -64,6 +83,9 @@
+                 E1000_FCT           = 0x00030, /* Flow Control Type */
+                 E1000_FCTTV         = 0x00170, /* Flow Control Transmit Timer Value */
+                 E1000_CRCERRS       = 0x04000, /* CRC Error Count (base address of the statistic register spaces) */
++                E1000_RAL           = 0x05400, /* Receive Address Low */
++                E1000_RAH           = 0x05404, /* Receive Address High */
++                E1000_MTA           = 0x05200, /* Multicast Table Array */
+             };
+         }
+ 
+@@ -132,7 +154,8 @@
+                 E1000_INTR_RXDMT0               = 0x00000010, /* rx desc min. threshold (0) */
+                 E1000_INTR_RXO                  = 0x00000040, /* rx overrun */
+                 E1000_INTR_RXT0                 = 0x00000080, /* rx timer intr (ring 0) */
+-                E1000_INTR_MDAC                 = 0x00000200  /* MDIO access complete */
++                E1000_INTR_MDAC                 = 0x00000200, /* MDIO access complete */
++                E1000_RAH_AV                    = (1 << 31),  /* Set the MAC Address as Valid */
+             };
+         }
+ 
+@@ -491,9 +514,32 @@
+             rtx_e1000_register_write32(&${ctx}->hw_ctx, E1000_FCAL, 0);
+             rtx_e1000_register_write32(&${ctx}->hw_ctx, E1000_FCT, 0);
+             rtx_e1000_register_write32(&${ctx}->hw_ctx, E1000_FCTTV, 0);
+-            int i = 0;
++            int i = 0; /* CNorm workaround, the init part of for isn't generated */
+             for (i = 0; i != 64; ++i)
+                 rtx_e1000_register_write32(&${ctx}->hw_ctx, E1000_CRCERRS + i * 4, 0);
++
++            /*
++             * Receive initialization
++             *
++             * - Program the receive address, in RAL/RAH;
++             * - Initialize the Multicast Table Array;
++             * - Program the interrupt mask register (done in
++             *   e1000::activate_device_interruption);
++             *
++             * (We should use uint{32,16}_t but CNorm doesn't know them yet)
++             */
++            rtx_e1000_register_write32(&${ctx}->hw_ctx, E1000_RAL,
++                    *(unsigned int *)(${ctx}->net_dev->dev_addr));
++            /*
++             * The 16 upper bits of RAH also store the AS bits (which should be
++             * 0) and the AV bit (should be 1 to set the address as valid).
++             */
++            rtx_e1000_register_write32(&${ctx}->hw_ctx, E1000_RAH,
++                    *(unsigned short *)(&${ctx}->net_dev->dev_addr[4]));
++            rtx_e1000_register_set32(&${ctx}->hw_ctx, E1000_RAH, E1000_RAH_AV);
++            i = 0; /* CNorm workaround, the init part of for isn't generated */
++            for (i = 0; i != 128; ++i)
++                rtx_e1000_register_write32(&${ctx}->hw_ctx, E1000_MTA + i * 4, 0);
+         }
+     }
+ 
+diff --git a/rathaxes/samples/e1000/e1000.rti b/rathaxes/samples/e1000/e1000.rti
+--- a/rathaxes/samples/e1000/e1000.rti
++++ b/rathaxes/samples/e1000/e1000.rti
+@@ -1,6 +1,8 @@
+ interface e1000 : Socket, Ethernet, PCI, LKM
+ {
+     provided type   e1000::Context;
++    provided type   e1000::RingRx;
++
+     /*
+      * These two types should actually be registers definitions in the frontend:
+      */
--- a/series	Sat Mar 03 17:07:32 2012 +0100
+++ b/series	Sun Mar 04 15:27:34 2012 +0100
@@ -1,3 +1,4 @@
 e1000_add_register_unset.patch
 e1000_fix_and_improve_set_up_device.patch
 e1000_use_log_info_in_card_status.patch
+e1000_initialize_reception.patch