changeset 40:0ff39df29c46

Add the code to reset the card
author Louis Opter <louis@lse.epitech.net>
date Sun, 08 Jan 2012 15:52:18 +0100
parents d761c8c625d3
children 87704b867fb0
files rathaxes_add_lkm_ethernet_sample.patch
diffstat 1 files changed, 164 insertions(+), 43 deletions(-) [+]
line wrap: on
line diff
--- a/rathaxes_add_lkm_ethernet_sample.patch	Sun Jan 08 14:47:03 2012 +0100
+++ b/rathaxes_add_lkm_ethernet_sample.patch	Sun Jan 08 15:52:18 2012 +0100
@@ -2,6 +2,18 @@
 # Parent b995d8934956b83383c144303178f3eb383d0acf
 rathaxes: add the PCI/Ethernet part of a Linux Intel e1000 network card driver
 
+diff --git a/maintainers/CMakeScripts/UseRathaxes.cmake b/maintainers/CMakeScripts/UseRathaxes.cmake
+--- a/maintainers/CMakeScripts/UseRathaxes.cmake
++++ b/maintainers/CMakeScripts/UseRathaxes.cmake
+@@ -193,6 +193,8 @@
+ 
+         SET(KERNEL_OBJECT_NAME "${RATHAXES_SOURCE}_${SYSTEM}.ko")
+         ADD_CUSTOM_COMMAND(OUTPUT "${KERNEL_OBJECT_NAME}"
++                           # …
++                           COMMAND "sed" "-i" "/TARTE/ d" "${RATHAXES_SOURCE}_${SYSTEM}.c"
+                            # The linux Makefile to build kernel module is quite
+                            # picky about file location and its own name. Let's
+                            # copy our source side by side with the Makefile:
 diff --git a/rathaxes/samples/CMakeLists.txt b/rathaxes/samples/CMakeLists.txt
 --- a/rathaxes/samples/CMakeLists.txt
 +++ b/rathaxes/samples/CMakeLists.txt
@@ -25,7 +37,7 @@
 new file mode 100644
 --- /dev/null
 +++ b/rathaxes/samples/lkm/e1000.blt
-@@ -0,0 +1,170 @@
+@@ -0,0 +1,267 @@
 +with e1000, Ethernet, Socket, PCI, LKM, Log
 +{
 +    template type   e1000::Context()
@@ -73,14 +85,14 @@
 +        {
 +            enum rtx_e1000_registers
 +            {
-+                E1000_CTRL = 0x00000,
-+                E1000_CTRL_DUP = 0x00004,
-+                E1000_STATUS = 0x00008,
-+                E1000_EEPROM_FLASH = 0x00010,
-+                E1000_EEPROM_READ = 0x00014,
-+                E1000_CTRL_EXT = 0x00018,
-+                E1000_FLA = 0x0001C,
-+                E1000_MDIC = 0x00020,
++                E1000_CTRL          = 0x00000, /* Device Control - RW */
++                E1000_CTRL_DUP      = 0x00004, /* Device Control Duplicate (Shadow) - RW */
++                E1000_STATUS        = 0x00008, /* Device Status - RO */
++                E1000_EEPROM_FLASH  = 0x00010, /* EEPROM/Flash Control - RW */
++                E1000_EEPROM_READ   = 0x00014, /* EEPROM Read - RW */
++                E1000_CTRL_EXT      = 0x00018, /* Extended Device Control - RW */
++                E1000_FLA           = 0x0001C, /* Flash Access - RW */
++                E1000_MDIC          = 0x00020  /* MDI Control - RW */
 +            };
 +        }
 +
@@ -94,6 +106,62 @@
 +        }
 +    }
 +
++    template type   e1000::Commands()
++    {
++        chunk   LKM::includes()
++        {
++            typedef int ${e1000::Commands};
++            static const ${e1000::Commands} force_enum_rtx_e1000_commands_decls;
++        }
++
++        chunk   ::decl()
++        {
++            enum rtx_e1000_commands
++            {
++                E1000_CMD_FD                    = 0x00000001, /* Full duplex.0=half; 1=full */
++                E1000_CMD_BEM                   = 0x00000002, /* Endian Mode.0=little,1=big */
++                E1000_CMD_PRIOR                 = 0x00000004, /* Priority on PCI. 0=rx,1=fair */
++                E1000_CMD_GIO_MASTER_DISABLE    = 0x00000004, /* Blocks new Master requests */
++                E1000_CMD_LRST                  = 0x00000008, /* Link reset. 0=normal,1=reset */
++                E1000_CMD_TME                   = 0x00000010, /* Test mode. 0=normal,1=test */
++                E1000_CMD_SLE                   = 0x00000020, /* Serial Link on 0=dis,1=en */
++                E1000_CMD_ASDE                  = 0x00000020, /* Auto-speed detect enable */
++                E1000_CMD_SLU                   = 0x00000040, /* Set link up (Force Link) */
++                E1000_CMD_ILOS                  = 0x00000080, /* Invert Loss-Of Signal */
++                E1000_CMD_SPD_SEL               = 0x00000300, /* Speed Select Mask */
++                E1000_CMD_SPD_10                = 0x00000000, /* Force 10Mb */
++                E1000_CMD_SPD_100               = 0x00000100, /* Force 100Mb */
++                E1000_CMD_SPD_1000              = 0x00000200, /* Force 1Gb */
++                E1000_CMD_BEM32                 = 0x00000400, /* Big Endian 32 mode */
++                E1000_CMD_FRCSPD                = 0x00000800, /* Force Speed */
++                E1000_CMD_FRCDPX                = 0x00001000, /* Force Duplex */
++                E1000_CMD_D_UD_EN               = 0x00002000, /* Dock/Undock enable */
++                E1000_CMD_D_UD_POLARITY         = 0x00004000, /* Defined polarity of Dock/Undock indication in SDP[0] */
++                E1000_CMD_FORCE_PHY_RESET       = 0x00008000, /* Reset both PHY ports, through PHYRST_N pin */
++                E1000_CMD_EXT_LINK_EN           = 0x00010000, /* enable link status from external LINK_0 and LINK_1 pins */
++                E1000_CMD_SWDPIN0               = 0x00040000, /* SWDPIN 0 value */
++                E1000_CMD_SWDPIN1               = 0x00080000, /* SWDPIN 1 value */
++                E1000_CMD_SWDPIN2               = 0x00100000, /* SWDPIN 2 value */
++                E1000_CMD_SWDPIN3               = 0x00200000, /* SWDPIN 3 value */
++                E1000_CMD_SWDPIO0               = 0x00400000, /* SWDPIN 0 Input or output */
++                E1000_CMD_SWDPIO1               = 0x00800000, /* SWDPIN 1 input or output */
++                E1000_CMD_SWDPIO2               = 0x01000000, /* SWDPIN 2 input or output */
++                E1000_CMD_SWDPIO3               = 0x02000000, /* SWDPIN 3 input or output */
++                E1000_CMD_RST                   = 0x04000000, /* Global reset */
++                E1000_CMD_RFCE                  = 0x08000000, /* Receive Flow Control enable */
++                E1000_CMD_TFCE                  = 0x10000000, /* Transmit flow control enable */
++                E1000_CMD_RTE                   = 0x20000000, /* Routing tag enable */
++                E1000_CMD_VME                   = 0x40000000, /* IEEE VLAN mode enable */
++                E1000_CMD_PHY_RST               = 0x80000000, /* PHY Reset */
++                E1000_CMD_SW2FW_INT             = 0x02000000  /* Initiate an interrupt to manageability engine */
++            };
++        }
++
++        map
++        {
++        }
++    }
++
 +    template sequence   e1000::create_device()
 +    {
 +        chunk Ethernet::create_device()
@@ -121,35 +189,12 @@
 +                ${Log::info("e1000::create: pci_ioremap_bar failed")};
 +            }
 +
-+            /* Now we can reset the card and load its mac address */
++            rtx_e1000_print_status(&rtx_ether_ctx->hw_ctx);
++            /* Reset the card */
++            rtx_e1000_register_write32(&rtx_ether_ctx->hw_ctx, E1000_CTRL, E1000_CMD_RST);
++            rtx_e1000_print_status(&rtx_ether_ctx->hw_ctx);
 +
-+            /*
-+             * We should have been able to do something along those lines, but
-+             * it didn't work so we made the call manually.
-+             *
-+             * Ideally:
-+             * ${e1000::register_read32(rtx_ether_ctx->hw_ctx, E1000_STATUS)};
-+             *
-+             * Ideally2, not sure about the syntax on the register parameter:
-+             * ${e1000::register_read32(rtx_ether_ctx->hw_ctx, ${e1000::Register.E1000_STATUS})};
-+             *
-+             * "Acceptable":
-+             * typedef int ${e1000::Register}; // cnorm __std__ workaround
-+             * ${e1000::Register} reg_status;
-+             * ${e1000.init(E1000_STATUS); // didn't work, so we used the next line
-+             * reg_status = E1000_STATUS;
-+             * ${e1000::register_read32(rtx_ether_ctx->hw_ctx, reg_status)};
-+             *
-+             */
-+
-+            unsigned int status = rtx_e1000_register_read32(&rtx_ether_ctx->hw_ctx, E1000_STATUS);
-+
-+            pr_info("Status of the e1000 card:\n");
-+            pr_info("\tStatus: %i\n", status);
-+            pr_info("\tMode: %s\n", (status & 1) ? "Full": "Half");
-+            pr_info("\tLink: %s\n", (status & 2) ? "UP" : "Down");
-+            pr_info("\tTransmission: %s\n", (status & 4) ? "Paused" : "Ok");
-+            pr_info("\tInterface: %s\n", (status & 3) == 3 ? "UP" : "Down");
++            /* Now we can load its mac address */
 +        }
 +
 +        chunk ::CALL
@@ -175,6 +220,49 @@
 +        }
 +    }
 +
++    template sequence   e1000::print_status()
++    {
++        chunk   LKM::prototypes()
++        {
++            static void rtx_e1000_print_status(struct rtx_e1000_ctx *);
++        }
++
++        chunk   LKM::code()
++        {
++            static void rtx_e1000_print_status(struct rtx_e1000_ctx *ctx)
++            {
++                unsigned int status = rtx_e1000_register_read32(ctx, E1000_STATUS);
++                pr_info("rtx_e1000 status: \n");
++                pr_info("\tRegister value: 0x%x\n", status);
++                pr_info("\tMode: %s\n", (status & 1) ? "Full": "Half");
++                pr_info("\tLink: %s\n", (status & 2) ? "Up" : "Down");
++                pr_info("\tTransmission: %s\n", (status & 4) ? "Paused" : "Ok");
++                pr_info("\tInterface: %s\n", (status & 3) == 3 ? "Up" : "Down");
++            }
++        }
++
++        chunk   ::CALL
++        {
++        }
++    }
++
++    /*
++     * We should have been able to do something along those lines, but
++     * it didn't work so we made the call manually.
++     *
++     * Ideally:
++     * ${e1000::register_read32(rtx_ether_ctx->hw_ctx, E1000_STATUS)};
++     *
++     * Ideally2, not sure about the syntax on the register parameter:
++     * ${e1000::register_read32(rtx_ether_ctx->hw_ctx, ${e1000::Register.E1000_STATUS})};
++     *
++     * "Acceptable":
++     * typedef int ${e1000::Register}; // cnorm __std__ workaround
++     * ${e1000::Register} reg_status;
++     * ${e1000.init(E1000_STATUS); // didn't work, so we used the next line
++     * reg_status = E1000_STATUS;
++     * ${e1000::register_read32(rtx_ether_ctx->hw_ctx, reg_status)};
++     */
 +    template sequence   e1000::register_read32(e1000::Context ctx, e1000::Register reg_offset)
 +    {
 +        chunk   LKM::prototypes()
@@ -195,16 +283,38 @@
 +            rtx_e1000_register_read32(&${ctx}, ${reg_offset});
 +        }
 +    }
++
++    template sequence   e1000::register_write32(e1000::Context ctx, e1000::Register reg_offset, ::number value)
++    {
++        chunk   LKM::prototypes()
++        {
++            static void rtx_e1000_register_write32(struct rtx_e1000_ctx *, unsigned int, unsigned int);
++        }
++
++        chunk   LKM::code()
++        {
++            static void rtx_e1000_register_write32(struct rtx_e1000_ctx *ctx, unsigned int reg_offset, unsigned int value)
++            {
++                iowrite32(value, ctx->ioaddr + reg_offset);
++            }
++        }
++
++        chunk   ::CALL()
++        {
++            rtx_e1000_register_write32(&${ctx}, ${reg_offset});
++        }
++    }
 +}
 diff --git a/rathaxes/samples/lkm/e1000.rti b/rathaxes/samples/lkm/e1000.rti
 new file mode 100644
 --- /dev/null
 +++ b/rathaxes/samples/lkm/e1000.rti
-@@ -0,0 +1,39 @@
+@@ -0,0 +1,51 @@
 +interface e1000 : Socket, Ethernet, PCI, LKM
 +{
 +    provided type   e1000::Context;
 +    provided type   e1000::Register;
++    provided type   e1000::Commands;
 +
 +    /*
 +     * This sequence should receive an argument like Ethernet::Device, but it is
@@ -227,18 +337,29 @@
 +    }
 +
 +    /*
-+     * It should also take an e1000::Context argument as the first parameter.
-+     * But we weren't able to call the sequence afterwards, with expression
-+     * like:
-+     *
-+     * ${e1000::register_read32(rtx_ether_ctx->hw_ctx, E1000_STATUS)};
++     * This should take an e1000::Context as the first argument but this was
++     * not working as wished.
 +     */
++    provided sequence   e1000::print_status()
++    {
++        provided chunk  LKM::prototypes;
++        provided chunk  LKM::code;
++        provided chunk  ::CALL;
++    }
++
 +    provided sequence   e1000::register_read32(e1000::Context, e1000::Register)
 +    {
 +        provided chunk  LKM::prototypes;
 +        provided chunk  LKM::code;
 +        provided chunk  ::CALL;
 +    }
++
++    provided sequence   e1000::register_write32(e1000::Context, e1000::Register, ::number)
++    {
++        provided chunk  LKM::prototypes;
++        provided chunk  LKM::code;
++        provided chunk  ::CALL;
++    }
 +}
 diff --git a/rathaxes/samples/lkm/ethernet.blt b/rathaxes/samples/lkm/ethernet.blt
 new file mode 100644