comparison rathaxes_add_lkm_ethernet_sample.patch @ 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
comparison
equal deleted inserted replaced
39:d761c8c625d3 40:0ff39df29c46
1 # HG changeset patch 1 # HG changeset patch
2 # Parent b995d8934956b83383c144303178f3eb383d0acf 2 # Parent b995d8934956b83383c144303178f3eb383d0acf
3 rathaxes: add the PCI/Ethernet part of a Linux Intel e1000 network card driver 3 rathaxes: add the PCI/Ethernet part of a Linux Intel e1000 network card driver
4 4
5 diff --git a/maintainers/CMakeScripts/UseRathaxes.cmake b/maintainers/CMakeScripts/UseRathaxes.cmake
6 --- a/maintainers/CMakeScripts/UseRathaxes.cmake
7 +++ b/maintainers/CMakeScripts/UseRathaxes.cmake
8 @@ -193,6 +193,8 @@
9
10 SET(KERNEL_OBJECT_NAME "${RATHAXES_SOURCE}_${SYSTEM}.ko")
11 ADD_CUSTOM_COMMAND(OUTPUT "${KERNEL_OBJECT_NAME}"
12 + # …
13 + COMMAND "sed" "-i" "/TARTE/ d" "${RATHAXES_SOURCE}_${SYSTEM}.c"
14 # The linux Makefile to build kernel module is quite
15 # picky about file location and its own name. Let's
16 # copy our source side by side with the Makefile:
5 diff --git a/rathaxes/samples/CMakeLists.txt b/rathaxes/samples/CMakeLists.txt 17 diff --git a/rathaxes/samples/CMakeLists.txt b/rathaxes/samples/CMakeLists.txt
6 --- a/rathaxes/samples/CMakeLists.txt 18 --- a/rathaxes/samples/CMakeLists.txt
7 +++ b/rathaxes/samples/CMakeLists.txt 19 +++ b/rathaxes/samples/CMakeLists.txt
8 @@ -1,2 +1,3 @@ 20 @@ -1,2 +1,3 @@
9 ADD_SUBDIRECTORY(helloworld) 21 ADD_SUBDIRECTORY(helloworld)
23 +ADD_RATHAXES_LKM(lkm lkm_src) 35 +ADD_RATHAXES_LKM(lkm lkm_src)
24 diff --git a/rathaxes/samples/lkm/e1000.blt b/rathaxes/samples/lkm/e1000.blt 36 diff --git a/rathaxes/samples/lkm/e1000.blt b/rathaxes/samples/lkm/e1000.blt
25 new file mode 100644 37 new file mode 100644
26 --- /dev/null 38 --- /dev/null
27 +++ b/rathaxes/samples/lkm/e1000.blt 39 +++ b/rathaxes/samples/lkm/e1000.blt
28 @@ -0,0 +1,170 @@ 40 @@ -0,0 +1,267 @@
29 +with e1000, Ethernet, Socket, PCI, LKM, Log 41 +with e1000, Ethernet, Socket, PCI, LKM, Log
30 +{ 42 +{
31 + template type e1000::Context() 43 + template type e1000::Context()
32 + { 44 + {
33 + chunk LKM::includes() 45 + chunk LKM::includes()
71 + 83 +
72 + chunk ::decl() 84 + chunk ::decl()
73 + { 85 + {
74 + enum rtx_e1000_registers 86 + enum rtx_e1000_registers
75 + { 87 + {
76 + E1000_CTRL = 0x00000, 88 + E1000_CTRL = 0x00000, /* Device Control - RW */
77 + E1000_CTRL_DUP = 0x00004, 89 + E1000_CTRL_DUP = 0x00004, /* Device Control Duplicate (Shadow) - RW */
78 + E1000_STATUS = 0x00008, 90 + E1000_STATUS = 0x00008, /* Device Status - RO */
79 + E1000_EEPROM_FLASH = 0x00010, 91 + E1000_EEPROM_FLASH = 0x00010, /* EEPROM/Flash Control - RW */
80 + E1000_EEPROM_READ = 0x00014, 92 + E1000_EEPROM_READ = 0x00014, /* EEPROM Read - RW */
81 + E1000_CTRL_EXT = 0x00018, 93 + E1000_CTRL_EXT = 0x00018, /* Extended Device Control - RW */
82 + E1000_FLA = 0x0001C, 94 + E1000_FLA = 0x0001C, /* Flash Access - RW */
83 + E1000_MDIC = 0x00020, 95 + E1000_MDIC = 0x00020 /* MDI Control - RW */
84 + }; 96 + };
85 + } 97 + }
86 + 98 +
87 + chunk ::init(value) 99 + chunk ::init(value)
88 + { 100 + {
89 + ${self} = ${value}; 101 + ${self} = ${value};
102 + }
103 +
104 + map
105 + {
106 + }
107 + }
108 +
109 + template type e1000::Commands()
110 + {
111 + chunk LKM::includes()
112 + {
113 + typedef int ${e1000::Commands};
114 + static const ${e1000::Commands} force_enum_rtx_e1000_commands_decls;
115 + }
116 +
117 + chunk ::decl()
118 + {
119 + enum rtx_e1000_commands
120 + {
121 + E1000_CMD_FD = 0x00000001, /* Full duplex.0=half; 1=full */
122 + E1000_CMD_BEM = 0x00000002, /* Endian Mode.0=little,1=big */
123 + E1000_CMD_PRIOR = 0x00000004, /* Priority on PCI. 0=rx,1=fair */
124 + E1000_CMD_GIO_MASTER_DISABLE = 0x00000004, /* Blocks new Master requests */
125 + E1000_CMD_LRST = 0x00000008, /* Link reset. 0=normal,1=reset */
126 + E1000_CMD_TME = 0x00000010, /* Test mode. 0=normal,1=test */
127 + E1000_CMD_SLE = 0x00000020, /* Serial Link on 0=dis,1=en */
128 + E1000_CMD_ASDE = 0x00000020, /* Auto-speed detect enable */
129 + E1000_CMD_SLU = 0x00000040, /* Set link up (Force Link) */
130 + E1000_CMD_ILOS = 0x00000080, /* Invert Loss-Of Signal */
131 + E1000_CMD_SPD_SEL = 0x00000300, /* Speed Select Mask */
132 + E1000_CMD_SPD_10 = 0x00000000, /* Force 10Mb */
133 + E1000_CMD_SPD_100 = 0x00000100, /* Force 100Mb */
134 + E1000_CMD_SPD_1000 = 0x00000200, /* Force 1Gb */
135 + E1000_CMD_BEM32 = 0x00000400, /* Big Endian 32 mode */
136 + E1000_CMD_FRCSPD = 0x00000800, /* Force Speed */
137 + E1000_CMD_FRCDPX = 0x00001000, /* Force Duplex */
138 + E1000_CMD_D_UD_EN = 0x00002000, /* Dock/Undock enable */
139 + E1000_CMD_D_UD_POLARITY = 0x00004000, /* Defined polarity of Dock/Undock indication in SDP[0] */
140 + E1000_CMD_FORCE_PHY_RESET = 0x00008000, /* Reset both PHY ports, through PHYRST_N pin */
141 + E1000_CMD_EXT_LINK_EN = 0x00010000, /* enable link status from external LINK_0 and LINK_1 pins */
142 + E1000_CMD_SWDPIN0 = 0x00040000, /* SWDPIN 0 value */
143 + E1000_CMD_SWDPIN1 = 0x00080000, /* SWDPIN 1 value */
144 + E1000_CMD_SWDPIN2 = 0x00100000, /* SWDPIN 2 value */
145 + E1000_CMD_SWDPIN3 = 0x00200000, /* SWDPIN 3 value */
146 + E1000_CMD_SWDPIO0 = 0x00400000, /* SWDPIN 0 Input or output */
147 + E1000_CMD_SWDPIO1 = 0x00800000, /* SWDPIN 1 input or output */
148 + E1000_CMD_SWDPIO2 = 0x01000000, /* SWDPIN 2 input or output */
149 + E1000_CMD_SWDPIO3 = 0x02000000, /* SWDPIN 3 input or output */
150 + E1000_CMD_RST = 0x04000000, /* Global reset */
151 + E1000_CMD_RFCE = 0x08000000, /* Receive Flow Control enable */
152 + E1000_CMD_TFCE = 0x10000000, /* Transmit flow control enable */
153 + E1000_CMD_RTE = 0x20000000, /* Routing tag enable */
154 + E1000_CMD_VME = 0x40000000, /* IEEE VLAN mode enable */
155 + E1000_CMD_PHY_RST = 0x80000000, /* PHY Reset */
156 + E1000_CMD_SW2FW_INT = 0x02000000 /* Initiate an interrupt to manageability engine */
157 + };
90 + } 158 + }
91 + 159 +
92 + map 160 + map
93 + { 161 + {
94 + } 162 + }
119 + if (!rtx_ether_ctx->hw_ctx.ioaddr) 187 + if (!rtx_ether_ctx->hw_ctx.ioaddr)
120 + { 188 + {
121 + ${Log::info("e1000::create: pci_ioremap_bar failed")}; 189 + ${Log::info("e1000::create: pci_ioremap_bar failed")};
122 + } 190 + }
123 + 191 +
124 + /* Now we can reset the card and load its mac address */ 192 + rtx_e1000_print_status(&rtx_ether_ctx->hw_ctx);
125 + 193 + /* Reset the card */
126 + /* 194 + rtx_e1000_register_write32(&rtx_ether_ctx->hw_ctx, E1000_CTRL, E1000_CMD_RST);
127 + * We should have been able to do something along those lines, but 195 + rtx_e1000_print_status(&rtx_ether_ctx->hw_ctx);
128 + * it didn't work so we made the call manually. 196 +
129 + * 197 + /* Now we can load its mac address */
130 + * Ideally:
131 + * ${e1000::register_read32(rtx_ether_ctx->hw_ctx, E1000_STATUS)};
132 + *
133 + * Ideally2, not sure about the syntax on the register parameter:
134 + * ${e1000::register_read32(rtx_ether_ctx->hw_ctx, ${e1000::Register.E1000_STATUS})};
135 + *
136 + * "Acceptable":
137 + * typedef int ${e1000::Register}; // cnorm __std__ workaround
138 + * ${e1000::Register} reg_status;
139 + * ${e1000.init(E1000_STATUS); // didn't work, so we used the next line
140 + * reg_status = E1000_STATUS;
141 + * ${e1000::register_read32(rtx_ether_ctx->hw_ctx, reg_status)};
142 + *
143 + */
144 +
145 + unsigned int status = rtx_e1000_register_read32(&rtx_ether_ctx->hw_ctx, E1000_STATUS);
146 +
147 + pr_info("Status of the e1000 card:\n");
148 + pr_info("\tStatus: %i\n", status);
149 + pr_info("\tMode: %s\n", (status & 1) ? "Full": "Half");
150 + pr_info("\tLink: %s\n", (status & 2) ? "UP" : "Down");
151 + pr_info("\tTransmission: %s\n", (status & 4) ? "Paused" : "Ok");
152 + pr_info("\tInterface: %s\n", (status & 3) == 3 ? "UP" : "Down");
153 + } 198 + }
154 + 199 +
155 + chunk ::CALL 200 + chunk ::CALL
156 + { 201 + {
157 + } 202 + }
173 + chunk ::CALL 218 + chunk ::CALL
174 + { 219 + {
175 + } 220 + }
176 + } 221 + }
177 + 222 +
223 + template sequence e1000::print_status()
224 + {
225 + chunk LKM::prototypes()
226 + {
227 + static void rtx_e1000_print_status(struct rtx_e1000_ctx *);
228 + }
229 +
230 + chunk LKM::code()
231 + {
232 + static void rtx_e1000_print_status(struct rtx_e1000_ctx *ctx)
233 + {
234 + unsigned int status = rtx_e1000_register_read32(ctx, E1000_STATUS);
235 + pr_info("rtx_e1000 status: \n");
236 + pr_info("\tRegister value: 0x%x\n", status);
237 + pr_info("\tMode: %s\n", (status & 1) ? "Full": "Half");
238 + pr_info("\tLink: %s\n", (status & 2) ? "Up" : "Down");
239 + pr_info("\tTransmission: %s\n", (status & 4) ? "Paused" : "Ok");
240 + pr_info("\tInterface: %s\n", (status & 3) == 3 ? "Up" : "Down");
241 + }
242 + }
243 +
244 + chunk ::CALL
245 + {
246 + }
247 + }
248 +
249 + /*
250 + * We should have been able to do something along those lines, but
251 + * it didn't work so we made the call manually.
252 + *
253 + * Ideally:
254 + * ${e1000::register_read32(rtx_ether_ctx->hw_ctx, E1000_STATUS)};
255 + *
256 + * Ideally2, not sure about the syntax on the register parameter:
257 + * ${e1000::register_read32(rtx_ether_ctx->hw_ctx, ${e1000::Register.E1000_STATUS})};
258 + *
259 + * "Acceptable":
260 + * typedef int ${e1000::Register}; // cnorm __std__ workaround
261 + * ${e1000::Register} reg_status;
262 + * ${e1000.init(E1000_STATUS); // didn't work, so we used the next line
263 + * reg_status = E1000_STATUS;
264 + * ${e1000::register_read32(rtx_ether_ctx->hw_ctx, reg_status)};
265 + */
178 + template sequence e1000::register_read32(e1000::Context ctx, e1000::Register reg_offset) 266 + template sequence e1000::register_read32(e1000::Context ctx, e1000::Register reg_offset)
179 + { 267 + {
180 + chunk LKM::prototypes() 268 + chunk LKM::prototypes()
181 + { 269 + {
182 + static unsigned int rtx_e1000_register_read32(struct rtx_e1000_ctx *, unsigned int); 270 + static unsigned int rtx_e1000_register_read32(struct rtx_e1000_ctx *, unsigned int);
193 + chunk ::CALL() 281 + chunk ::CALL()
194 + { 282 + {
195 + rtx_e1000_register_read32(&${ctx}, ${reg_offset}); 283 + rtx_e1000_register_read32(&${ctx}, ${reg_offset});
196 + } 284 + }
197 + } 285 + }
286 +
287 + template sequence e1000::register_write32(e1000::Context ctx, e1000::Register reg_offset, ::number value)
288 + {
289 + chunk LKM::prototypes()
290 + {
291 + static void rtx_e1000_register_write32(struct rtx_e1000_ctx *, unsigned int, unsigned int);
292 + }
293 +
294 + chunk LKM::code()
295 + {
296 + static void rtx_e1000_register_write32(struct rtx_e1000_ctx *ctx, unsigned int reg_offset, unsigned int value)
297 + {
298 + iowrite32(value, ctx->ioaddr + reg_offset);
299 + }
300 + }
301 +
302 + chunk ::CALL()
303 + {
304 + rtx_e1000_register_write32(&${ctx}, ${reg_offset});
305 + }
306 + }
198 +} 307 +}
199 diff --git a/rathaxes/samples/lkm/e1000.rti b/rathaxes/samples/lkm/e1000.rti 308 diff --git a/rathaxes/samples/lkm/e1000.rti b/rathaxes/samples/lkm/e1000.rti
200 new file mode 100644 309 new file mode 100644
201 --- /dev/null 310 --- /dev/null
202 +++ b/rathaxes/samples/lkm/e1000.rti 311 +++ b/rathaxes/samples/lkm/e1000.rti
203 @@ -0,0 +1,39 @@ 312 @@ -0,0 +1,51 @@
204 +interface e1000 : Socket, Ethernet, PCI, LKM 313 +interface e1000 : Socket, Ethernet, PCI, LKM
205 +{ 314 +{
206 + provided type e1000::Context; 315 + provided type e1000::Context;
207 + provided type e1000::Register; 316 + provided type e1000::Register;
317 + provided type e1000::Commands;
208 + 318 +
209 + /* 319 + /*
210 + * This sequence should receive an argument like Ethernet::Device, but it is 320 + * This sequence should receive an argument like Ethernet::Device, but it is
211 + * unclear about how this argument should be bound to a variable/argument in 321 + * unclear about how this argument should be bound to a variable/argument in
212 + * the instrumented C code. 322 + * the instrumented C code.
225 + provided chunk Ethernet::destroy_device; 335 + provided chunk Ethernet::destroy_device;
226 + provided chunk ::CALL; 336 + provided chunk ::CALL;
227 + } 337 + }
228 + 338 +
229 + /* 339 + /*
230 + * It should also take an e1000::Context argument as the first parameter. 340 + * This should take an e1000::Context as the first argument but this was
231 + * But we weren't able to call the sequence afterwards, with expression 341 + * not working as wished.
232 + * like:
233 + *
234 + * ${e1000::register_read32(rtx_ether_ctx->hw_ctx, E1000_STATUS)};
235 + */ 342 + */
343 + provided sequence e1000::print_status()
344 + {
345 + provided chunk LKM::prototypes;
346 + provided chunk LKM::code;
347 + provided chunk ::CALL;
348 + }
349 +
236 + provided sequence e1000::register_read32(e1000::Context, e1000::Register) 350 + provided sequence e1000::register_read32(e1000::Context, e1000::Register)
351 + {
352 + provided chunk LKM::prototypes;
353 + provided chunk LKM::code;
354 + provided chunk ::CALL;
355 + }
356 +
357 + provided sequence e1000::register_write32(e1000::Context, e1000::Register, ::number)
237 + { 358 + {
238 + provided chunk LKM::prototypes; 359 + provided chunk LKM::prototypes;
239 + provided chunk LKM::code; 360 + provided chunk LKM::code;
240 + provided chunk ::CALL; 361 + provided chunk ::CALL;
241 + } 362 + }