Mercurial > archived > louis > epitech > mq > rathaxes
comparison rathaxes_sample_e1000_rewrite_device_dependent_code.patch @ 133:dbb4a3b383cb
Wip on build
author | Louis Opter <kalessin@kalessin.fr> |
---|---|
date | Wed, 08 Jan 2014 09:42:33 -0800 |
parents | f2e4dd91dc6f |
children | 79226bb06e6a |
comparison
equal
deleted
inserted
replaced
132:f2e4dd91dc6f | 133:dbb4a3b383cb |
---|---|
1 # HG changeset patch | 1 # HG changeset patch |
2 # Parent 7d00455945ec97c5851ac0d735da7c3cfbd8e39c | 2 # Parent 53d3ca9da9c4cd680cf5982b9e972903fb4d3231 |
3 rathaxes: rewrite/refactor all the e1000 device dependent code | 3 rathaxes: rewrite/refactor all the e1000 device dependent code |
4 | 4 |
5 diff --git a/notes.txt b/notes.txt | 5 diff --git a/notes.txt b/notes.txt |
6 new file mode 100644 | 6 new file mode 100644 |
7 --- /dev/null | 7 --- /dev/null |
8 +++ b/notes.txt | 8 +++ b/notes.txt |
9 @@ -0,0 +1,26 @@ | 9 @@ -0,0 +1,40 @@ |
10 +Remarks for David & Lionel: | 10 +Remarks for David & Lionel: |
11 + | 11 + |
12 +- Too much changes to not start over; | 12 +- Too much changes to not start over; |
13 +- Lack of methods is extremely annoying and requires a lot of workarounds (e.g: | 13 +- Lack of methods is extremely annoying and requires a lot of workarounds (e.g: |
14 + see the register read/write/set/unset methods on e1000::Context); | 14 + see the register read/write/set/unset methods on e1000::Context); |
21 +- Can I use the same name for a pointcut and a sequence (e.g: Ethernet::send | 21 +- Can I use the same name for a pointcut and a sequence (e.g: Ethernet::send |
22 + bot a sequence name and a pointcut same thing for the interrupt handler); | 22 + bot a sequence name and a pointcut same thing for the interrupt handler); |
23 +- Lack of support for circular dependencies make some code annoying or | 23 +- Lack of support for circular dependencies make some code annoying or |
24 + incorrect (circular dependencies between abstract and concrete types via the | 24 + incorrect (circular dependencies between abstract and concrete types via the |
25 + attribute or circular dependencies between the rings and the hardware | 25 + attribute or circular dependencies between the rings and the hardware |
26 + context). | 26 + context); |
27 +- It would be really cool to passthrough the comments; | |
28 +- Not being able to use a Rathaxes type in the attributes is really annoying | |
29 + and forces me to hardcode a lot of stuff; | |
30 +- Pointcuts are scoped by subsystems which is kinda weird because different | |
31 + subsystems are going to share the same pointcuts (i.e: the PCI and USB | |
32 + susystem are going to expose the same pointcuts that can be used by the | |
33 + Ethernet subsystem). | |
27 + | 34 + |
28 +Todo/Totry: | 35 +Todo/Totry: |
29 + | 36 + |
30 +- Use the rtx_ether_ctx attribute on AbstractDevice to initialize Device | 37 +- Use the rtx_ether_ctx attribute on AbstractDevice to initialize Device |
31 + objects in ethernet.bl; | 38 + objects in ethernet.bl; |
32 +- Worry about the code being executed concurrently, e.g: what happens if the | 39 +- Worry about the code being executed concurrently, e.g: what happens if the |
33 + interrupt handler is called right before we disable it in the close path? | 40 + interrupt handler is called right before we disable it in the close path? |
41 +- Why the DMA sequences are taking an AbstractDMAHandle instead of a DMAHandle? | |
34 + | 42 + |
35 +Questions: | 43 +Questions: |
44 + | |
45 +Compiler bugs: | |
46 + | |
47 +- Trying to expand a type that doesn't exists crashes the compiler instead of | |
48 + displaying something more useful (took me 15 minutes to figure out that I | |
49 + typed 3 colons instead of 2 in a placeholder). | |
50 diff --git a/rathaxes/compiler/passes/back/rtxIntrospect.inc.cws b/rathaxes/compiler/passes/back/rtxIntrospect.inc.cws | |
51 --- a/rathaxes/compiler/passes/back/rtxIntrospect.inc.cws | |
52 +++ b/rathaxes/compiler/passes/back/rtxIntrospect.inc.cws | |
53 @@ -890,6 +890,8 @@ | |
54 local to_remove; | |
55 foreach placeHolder in local_node.body.compile | |
56 { | |
57 + if (!placeHolder.node.body.type) | |
58 + traceLine(RED + "BUG: placeHolder.node.body.type is missing in rtxIntrospect_walk<\"__rtx_chunk__\">" + DEFAULT_COLOR); | |
59 if (rtxIntrospect_InferPlaceHolderTypes<placeHolder.node.body.type>(placeHolder.node.body, local_node) == false) | |
60 { | |
61 pushItem to_remove; | |
62 diff --git a/rathaxes/compiler/passes/back/rtxPlaceHolders.inc.cws b/rathaxes/compiler/passes/back/rtxPlaceHolders.inc.cws | |
63 --- a/rathaxes/compiler/passes/back/rtxPlaceHolders.inc.cws | |
64 +++ b/rathaxes/compiler/passes/back/rtxPlaceHolders.inc.cws | |
65 @@ -394,7 +394,10 @@ | |
66 { rtxPH_mapPlaceHolder(local_node.expr.id, compile, node_idx, "target_pointcut"); } | |
67 } | |
68 else | |
69 + { | |
70 + traceLine(CYAN + "LOUIS: local_node.expr: " + toString(local_node.expr) + DEFAULT_COLOR); | |
71 rtxPH_compile<local_node.expr.type>(local_node.expr, compile, node_idx); | |
72 + } | |
73 } | |
74 // Label | |
75 if (existVariable(local_node.label) && rtxPH_havePlaceHolder(local_node.label)) | |
36 diff --git a/rathaxes/samples/e1000/CMakeLists.txt b/rathaxes/samples/e1000/CMakeLists.txt | 76 diff --git a/rathaxes/samples/e1000/CMakeLists.txt b/rathaxes/samples/e1000/CMakeLists.txt |
37 old mode 100755 | |
38 new mode 100644 | |
39 --- a/rathaxes/samples/e1000/CMakeLists.txt | 77 --- a/rathaxes/samples/e1000/CMakeLists.txt |
40 +++ b/rathaxes/samples/e1000/CMakeLists.txt | 78 +++ b/rathaxes/samples/e1000/CMakeLists.txt |
41 @@ -17,9 +17,9 @@ | 79 @@ -17,9 +17,9 @@ |
42 dma.blt | 80 dma.blt |
43 pci.blt | 81 pci.blt |
51 - ADD_RATHAXES_LKM(e1000 e1000_src) | 89 - ADD_RATHAXES_LKM(e1000 e1000_src) |
52 -ENDIF (LINUX_KBUILD_DIR) | 90 -ENDIF (LINUX_KBUILD_DIR) |
53 +#IF (LINUX_KBUILD_DIR) | 91 +#IF (LINUX_KBUILD_DIR) |
54 +# ADD_RATHAXES_LKM(e1000 e1000_src) | 92 +# ADD_RATHAXES_LKM(e1000 e1000_src) |
55 +#ENDIF (LINUX_KBUILD_DIR) | 93 +#ENDIF (LINUX_KBUILD_DIR) |
56 diff --git a/rathaxes/samples/e1000/dma.blt b/rathaxes/samples/e1000/dma.blt | |
57 old mode 100755 | |
58 new mode 100644 | |
59 diff --git a/rathaxes/samples/e1000/dma.rti b/rathaxes/samples/e1000/dma.rti | |
60 old mode 100755 | |
61 new mode 100644 | |
62 diff --git a/rathaxes/samples/e1000/e1000.blt b/rathaxes/samples/e1000/e1000.blt | 94 diff --git a/rathaxes/samples/e1000/e1000.blt b/rathaxes/samples/e1000/e1000.blt |
63 old mode 100755 | |
64 new mode 100644 | |
65 --- a/rathaxes/samples/e1000/e1000.blt | 95 --- a/rathaxes/samples/e1000/e1000.blt |
66 +++ b/rathaxes/samples/e1000/e1000.blt | 96 +++ b/rathaxes/samples/e1000/e1000.blt |
67 @@ -1,8 +1,148 @@ | 97 @@ -1,564 +1,8 @@ |
68 with e1000, Ethernet, Socket, DMA, PCI, LKM, Log, Builtin | 98 -with e1000, Ethernet, Socket, DMA, PCI, LKM, Log, Builtin |
99 +with e1000, Ethernet, Socket, Device, DMA, PCI, LKM, Log, Builtin | |
69 { | 100 { |
70 - template type e1000::RxDescriptor() | 101 - template type e1000::RxDescriptor() |
71 + template type e1000::Register() | 102 + template type e1000::Register() |
72 { | 103 { |
73 - decl data_types() | 104 - decl data_types() |
74 + decl data_types() | 105 - { |
75 + { | 106 - __le64 buff_addr; |
76 + E1000_CTRL = 0x00000, /* Device Control - RW */ | 107 - __le16 length; |
77 + E1000_CTRL_DUP = 0x00004, /* Device Control Duplicate (Shadow) - RW */ | 108 - __le16 csum; |
78 + E1000_STATUS = 0x00008, /* Device Status - RO */ | 109 - unsigned char status; |
79 + E1000_EEPROM_FLASH = 0x00010, /* EEPROM/Flash Control - RW */ | 110 - unsigned char errors; |
80 + E1000_EEPROM_READ = 0x00014, /* EEPROM Read - RW */ | 111 - __le16 special; |
81 + E1000_CTRL_EXT = 0x00018, /* Extended Device Control - RW */ | 112 - } |
82 + E1000_FLA = 0x0001C, /* Flash Access - RW */ | 113 - |
83 + E1000_MDIC = 0x00020, /* MDI Control - RW */ | |
84 + E1000_IMS = 0x000D0, /* Interrupt Mask Set */ | |
85 + E1000_IMC = 0x000D8, /* Interrupt Mask Clear */ | |
86 + E1000_ICR = 0x000C0, /* Interrupt Cause Read - R/clr */ | |
87 + E1000_FCAL = 0x00028, /* Flow Control Address Low */ | |
88 + E1000_FCAH = 0x0002c, /* Flow Control Address High */ | |
89 + E1000_FCT = 0x00030, /* Flow Control Type */ | |
90 + E1000_RCTL = 0x00100, /* Receive Control */ | |
91 + E1000_FCTTV = 0x00170, /* Flow Control Transmit Timer Value */ | |
92 + E1000_TCTL = 0x00400, /* Transmit Control */ | |
93 + E1000_CRCERRS = 0x04000, /* CRC Error Count (base address of the statistic register spaces) */ | |
94 + E1000_RAL = 0x05400, /* Receive Address Low */ | |
95 + E1000_RAH = 0x05404, /* Receive Address High */ | |
96 + E1000_MTA = 0x05200, /* Multicast Table Array */ | |
97 + E1000_RDBAL = 0x02800, /* Receive Descriptor Base Address (Low 32 bits) */ | |
98 + E1000_RDBAH = 0x02804, /* Receive Descriptor Base Address (High 32 bits) */ | |
99 + E1000_RDLEN = 0x02808, /* Receive Descriptor Length */ | |
100 + E1000_RDH = 0x02810, /* Receive Descriptor Head */ | |
101 + E1000_RDT = 0x02818, /* Receive Descriptor Tail */ | |
102 + E1000_TDBAL = 0x03800, /* Transmit Descriptor Base Address (Low 32 bits) */ | |
103 + E1000_TDBAH = 0x03804, /* Transmit Descriptor Base Address (High 33 bits) */ | |
104 + E1000_TDLEN = 0x03808, /* Transmit Descriptor Length */ | |
105 + E1000_TDH = 0x03810, /* Transmit Descriptor Head */ | |
106 + E1000_TDT = 0x03818, /* Transmit Descriptor Tail */ | |
107 + } | |
108 + | |
109 + map | |
110 + { | |
111 + } | |
112 + } | |
113 + | |
114 + template type e1000::Commands() | |
115 + { | |
116 + decl data_types() | |
117 + { | |
118 + E1000_CMD_FD = 0x00000001, /* Full duplex.0=half; 1=full */ | |
119 + E1000_CMD_BEM = 0x00000002, /* Endian Mode.0=little,1=big */ | |
120 + E1000_CMD_PRIOR = 0x00000004, /* Priority on PCI. 0=rx,1=fair */ | |
121 + E1000_CMD_GIO_MASTER_DISABLE = 0x00000004, /* Blocks new Master requests */ | |
122 + E1000_CMD_LRST = 0x00000008, /* Link reset. 0=normal,1=reset */ | |
123 + E1000_CMD_TME = 0x00000010, /* Test mode. 0=normal,1=test */ | |
124 + E1000_CMD_SLE = 0x00000020, /* Serial Link on 0=dis,1=en */ | |
125 + E1000_CMD_ASDE = 0x00000020, /* Auto-speed detect enable */ | |
126 + E1000_CMD_SLU = 0x00000040, /* Set link up (Force Link) */ | |
127 + E1000_CMD_ILOS = 0x00000080, /* Invert Loss-Of Signal */ | |
128 + E1000_CMD_SPD_SEL = 0x00000300, /* Speed Select Mask */ | |
129 + E1000_CMD_SPD_10 = 0x00000000, /* Force 10Mb */ | |
130 + E1000_CMD_SPD_100 = 0x00000100, /* Force 100Mb */ | |
131 + E1000_CMD_SPD_1000 = 0x00000200, /* Force 1Gb */ | |
132 + E1000_CMD_BEM32 = 0x00000400, /* Big Endian 32 mode */ | |
133 + E1000_CMD_FRCSPD = 0x00000800, /* Force Speed */ | |
134 + E1000_CMD_FRCDPX = 0x00001000, /* Force Duplex */ | |
135 + E1000_CMD_D_UD_EN = 0x00002000, /* Dock/Undock enable */ | |
136 + E1000_CMD_D_UD_POLARITY = 0x00004000, /* Defined polarity of Dock/Undock indication in SDP[0] */ | |
137 + E1000_CMD_FORCE_PHY_RESET = 0x00008000, /* Reset both PHY ports, through PHYRST_N pin */ | |
138 + E1000_CMD_EXT_LINK_EN = 0x00010000, /* enable link status from external LINK_0 and LINK_1 pins */ | |
139 + E1000_CMD_SWDPIN0 = 0x00040000, /* SWDPIN 0 value */ | |
140 + E1000_CMD_SWDPIN1 = 0x00080000, /* SWDPIN 1 value */ | |
141 + E1000_CMD_SWDPIN2 = 0x00100000, /* SWDPIN 2 value */ | |
142 + E1000_CMD_SWDPIN3 = 0x00200000, /* SWDPIN 3 value */ | |
143 + E1000_CMD_SWDPIO0 = 0x00400000, /* SWDPIN 0 Input or output */ | |
144 + E1000_CMD_SWDPIO1 = 0x00800000, /* SWDPIN 1 input or output */ | |
145 + E1000_CMD_SWDPIO2 = 0x01000000, /* SWDPIN 2 input or output */ | |
146 + E1000_CMD_SWDPIO3 = 0x02000000, /* SWDPIN 3 input or output */ | |
147 + E1000_CMD_RST = 0x04000000, /* Global reset */ | |
148 + E1000_CMD_RFCE = 0x08000000, /* Receive Flow Control enable */ | |
149 + E1000_CMD_TFCE = 0x10000000, /* Transmit flow control enable */ | |
150 + E1000_CMD_RTE = 0x20000000, /* Routing tag enable */ | |
151 + E1000_CMD_VME = 0x40000000, /* IEEE VLAN mode enable */ | |
152 + E1000_CMD_PHY_RST = 0x80000000, /* PHY Reset */ | |
153 + E1000_CMD_SW2FW_INT = 0x02000000, /* Initiate an interrupt to manageability engine */ | |
154 + E1000_INTR_TXDW = 0x00000001, /* Transmit desc written back */ | |
155 + E1000_INTR_TXQE = 0x00000002, /* Transmit Queue empty */ | |
156 + E1000_INTR_LSC = 0x00000004, /* Link Status Change */ | |
157 + E1000_INTR_RXSEQ = 0x00000008, /* rx sequence error */ | |
158 + E1000_INTR_RXDMT0 = 0x00000010, /* rx desc min. threshold (0) */ | |
159 + E1000_INTR_RXO = 0x00000040, /* rx overrun */ | |
160 + E1000_INTR_RXT0 = 0x00000080, /* rx timer intr (ring 0) */ | |
161 + E1000_INTR_MDAC = 0x00000200, /* MDIO access complete */ | |
162 + E1000_RAH_AV = (1 << 31), /* Set the MAC Address as Valid */ | |
163 + E1000_RCTL_EN = (1 << 1), /* Receiver Enable */ | |
164 + E1000_RCTL_BSEX = (1 << 25), /* Buffer Size Extension */ | |
165 + E1000_RCTL_BSIZE_256 = ((1 << 16) | (1 << 17)), | |
166 + E1000_RCTL_BSIZE_512 = (1 << 17), | |
167 + E1000_RCTL_BSIZE_1024 = (1 << 16), | |
168 + E1000_RCTL_BSIZE_2048 = 0, | |
169 + E1000_RCTL_BSIZE_4096 = (E1000_RCTL_BSEX | (1 << 16) | (1 << 17)), | |
170 + E1000_RCTL_BSIZE_8192 = (E1000_RCTL_BSEX | (1 << 17)), | |
171 + E1000_RCTL_BSIZE_16384 = (E1000_RCTL_BSEX | (1 << 16)), | |
172 + E1000_TCTL_EN = (1 << 1), /* Transmitter Enable */ | |
173 + E1000_TCTL_PSP = (1 << 3), /* Pad Short Packet */ | |
174 + } | |
175 + | |
176 + map | |
177 + { | |
178 + } | |
179 + } | |
180 + | |
181 + template type e1000::TxDescriptorFlag() | |
182 + { | |
183 + decl data_types() | |
184 + { | |
185 + E1000_TXD_DTYP_D = 0x00100000, /* Data Descriptor */ | |
186 + E1000_TXD_DTYP_C = 0x00000000, /* Context Descriptor */ | |
187 + E1000_TXD_POPTS_IXSM = 0x01, /* Insert IP checksum */ | |
188 + E1000_TXD_POPTS_TXSM = 0x02, /* Insert TCP/UDP checksum */ | |
189 + E1000_TXD_CMD_EOP = 0x01000000, /* End of Packet */ | |
190 + E1000_TXD_CMD_IFCS = 0x02000000, /* Insert FCS (Ethernet CRC) */ | |
191 + E1000_TXD_CMD_IC = 0x04000000, /* Insert Checksum */ | |
192 + E1000_TXD_CMD_RS = 0x08000000, /* Report Status */ | |
193 + E1000_TXD_CMD_RPS = 0x10000000, /* Report Packet Sent */ | |
194 + E1000_TXD_CMD_DEXT = 0x20000000, /* Descriptor extension (0 = legacy) */ | |
195 + E1000_TXD_CMD_VLE = 0x40000000, /* Add VLAN tag */ | |
196 + E1000_TXD_CMD_IDE = 0x80000000, /* Enable Tidv register */ | |
197 + E1000_TXD_STAT_DD = 0x00000001, /* Descriptor Done */ | |
198 + E1000_TXD_STAT_EC = 0x00000002, /* Excess Collisions */ | |
199 + E1000_TXD_STAT_LC = 0x00000004, /* Late Collisions */ | |
200 + E1000_TXD_STAT_TU = 0x00000008, /* Transmit underrun */ | |
201 + E1000_TXD_CMD_TCP = 0x01000000, /* TCP packet */ | |
202 + E1000_TXD_CMD_IP = 0x02000000, /* IP packet */ | |
203 + E1000_TXD_CMD_TSE = 0x04000000, /* TCP Seg enable */ | |
204 + E1000_TXD_STAT_TC = 0x00000004, /* Tx Underrun */ | |
205 + } | |
206 + | |
207 + map | |
208 + { | |
209 + } | |
210 + } | |
211 + | |
212 + template type e1000::RxDescriptor() | |
213 + { | |
214 + decl data_types() | |
215 { | |
216 __le64 buff_addr; | |
217 __le16 length; | |
218 @@ -12,13 +152,39 @@ | |
219 __le16 special; | |
220 } | |
221 | |
222 - chunk LKM::includes() | 114 - chunk LKM::includes() |
223 + map | 115 - { |
224 { | |
225 - #include <linux/types.h> | 116 - #include <linux/types.h> |
226 } | 117 - } |
227 + } | 118 - |
228 | |
229 - method init() | 119 - method init() |
230 + // This is a generic tx descriptor for the e1000. When you use TCP | 120 - { |
231 + // Segmentation Offload (TSO) the hardware actually uses two types of | 121 - } |
232 + // tx descriptors in its tx ring: | 122 - |
233 + // - context descriptors: this descriptor doesn't actually point to data to | 123 - map |
234 + // send but initialize the offloading engine for the data descriptor that | 124 - { |
235 + // follow; | 125 - } |
236 + // - data descriptors: this descriptor points to data from the skbuffs. | 126 - } |
237 + template type e1000::TxDescriptor() | 127 - |
238 + { | |
239 + decl data_types() | |
240 { | |
241 + __le64 buff_addr; | |
242 + union { | |
243 + __le32 data; | |
244 + struct { | |
245 + __le16 length; | |
246 + unsigned char csum_offset; /* CSO */ | |
247 + unsigned char cmd; | |
248 + } fields; | |
249 + } lower; | |
250 + union { | |
251 + __le32 data; | |
252 + struct { | |
253 + unsigned char status; | |
254 + unsigned char csum_start; /* CSS */ | |
255 + __le16 special; | |
256 + } fields; | |
257 + } upper; | |
258 } | |
259 | |
260 map | |
261 @@ -26,44 +192,131 @@ | |
262 } | |
263 } | |
264 | |
265 - /* | 128 - /* |
266 - * This is a generic tx descriptor for the e1000. When you use TCP | 129 - * This is a generic tx descriptor for the e1000. When you use TCP |
267 - * Segmentation Offload (TSO) the hardware actually uses two types of | 130 - * Segmentation Offload (TSO) the hardware actually uses two types of |
268 - * tx descriptors in its tx ring: | 131 - * tx descriptors in its tx ring: |
269 - * - context descriptors: this descriptor doesn't actually point to data to | 132 - * - context descriptors: this descriptor doesn't actually point to data to |
270 - * send but initialize the offloading engine for the data descriptor that | 133 - * send but initialize the offloading engine for the data descriptor that |
271 - * follow; | 134 - * follow; |
272 - * - data descriptors: this descriptor points to data from the skbuffs. | 135 - * - data descriptors: this descriptor points to data from the skbuffs. |
273 - */ | 136 - */ |
274 - template type e1000::TxDescriptor() | 137 - template type e1000::TxDescriptor() |
275 + template type e1000::Buffer() | 138 - { |
276 { | |
277 - decl data_types() | 139 - decl data_types() |
278 + decl data_types() | 140 - { |
279 { | |
280 - __le64 buff_addr; | 141 - __le64 buff_addr; |
281 - union | 142 - union |
282 - { | 143 - { |
283 - __le32 data; | 144 - __le32 data; |
284 - struct | 145 - struct |
296 - unsigned char status; | 157 - unsigned char status; |
297 - unsigned char csum_start; /* CSS */ | 158 - unsigned char csum_start; /* CSS */ |
298 - __le16 special; | 159 - __le16 special; |
299 - } fields; | 160 - } fields; |
300 - } upper; | 161 - } upper; |
301 + ${Socket::SKBuff} sk_buff; | 162 - } |
302 + ${DMA::DMAHandle} dma; | 163 - |
303 } | |
304 | |
305 - method init() | 164 - method init() |
306 + method init(Socket::SKBuff sk_buff, DMA::DMAHandle dma) | 165 - { |
307 { | 166 - } |
308 + ${self.sk_buff} = ${sk_buff}; | 167 - |
309 + ${self.dma} = ${dma}; | 168 - map |
310 + } | 169 - { |
311 + | 170 - } |
312 + map | 171 - } |
313 + { | 172 - |
314 + sk_buff: ${self}->sk_buff; | |
315 + dma: ${self}->dma; | |
316 + } | |
317 + } | |
318 + | |
319 + template type e1000::MMIO() | |
320 + { | |
321 + decl data_types() | |
322 + { | |
323 + unsigned char *io; | |
324 + } | |
325 + | |
326 + // XXX: we'll need those functions until we get working methods (#46): | |
327 + | |
328 + chunk LKM::prototypes() | |
329 + { | |
330 + static unsigned int rtx_e1000_reg_read32(${e1000::MMIO}, ${e1000::Register}); | |
331 + static void rtx_e1000_reg_write32(${e1000:::MMIO}, ${e1000::Register}, ${Builtin::number}); | |
332 + static void rtx_e1000_reg_set32(${e1000:::MMIO}, ${e1000::Register}, ${Builtin::number}); | |
333 + static void rtx_e1000_reg_unset32(${e1000:::MMIO}, ${e1000::Register}, ${Builtin::number}); | |
334 + } | |
335 + | |
336 + chunk LKM::code() | |
337 + { | |
338 + static unsigned int rtx_e1000_reg_read32(${e1000::MMIO} io, ${e1000::Register} reg) | |
339 + { | |
340 + return ioread32(${local.io.io} + reg); | |
341 + } | |
342 + | |
343 + static void rtx_e1000_reg_write32(${e1000:::MMIO} io, ${e1000::Register} reg, ${Builtin::number} value) | |
344 + { | |
345 + return iowrite32(value, ${local.io.io} + reg); | |
346 + } | |
347 + | |
348 + static void rtx_e1000_reg_set32(${e1000:::MMIO} io, ${e1000::Register} reg, ${Builtin::number} value) | |
349 + { | |
350 + return iowrite32(rtx_e1000_reg_read32(io, reg) | value, ${local.io.io} + reg); | |
351 + } | |
352 + | |
353 + static void rtx_e1000_reg_unset32(${e1000:::MMIO} io, ${e1000::Register} reg, ${Builtin::number} value) | |
354 + { | |
355 + return iowrite32(rtx_e1000_reg_read32(io, reg) & ~value, ${local.io.io} + reg); | |
356 + } | |
357 + } | |
358 + | |
359 + method init(Builtin::symbol io) | |
360 + { | |
361 + ${self.io} = ${io}; | |
362 + } | |
363 + | |
364 + method read32(e1000::Register reg) | |
365 + { | |
366 + ioread32(${self.io} + ${local.reg}); | |
367 + } | |
368 + | |
369 + method write32(e1000::Register reg, Builtin::number value) | |
370 + { | |
371 + iowrite32(${local.value}, ${self.io} + ${local.reg}); | |
372 + } | |
373 + | |
374 + method set32(e1000::Register reg, Builtin::number value) | |
375 + { | |
376 + iowrite32(ioread32(${self.io} + ${local.reg}) | value, ${self.io} + ${local.reg}); | |
377 + } | |
378 + | |
379 + method unset32(e1000::Register reg, Builtin::number value) | |
380 + { | |
381 + iowrite32(ioread32(${self.io} + ${local.reg}) & ~value, ${self.io} + ${local.reg}); | |
382 + } | |
383 + | |
384 + map | |
385 + { | |
386 + io: ((unsigned char *)(${self})); | |
387 + } | |
388 + } | |
389 + | |
390 + template type e1000::Ring() | |
391 + { | |
392 + decl data_types() | |
393 + { | |
394 + ${e1000::MMIO} io; | |
395 + ${DMA::DMAHandle} dma; | |
396 + ${Builtin::symbol.ref} descs; | |
397 + ${Builtin::number} size; | |
398 + ${e1000::Buffer.ref} buffs; | |
399 + } | |
400 + | |
401 + chunk LKM::prototypes() | |
402 + { | |
403 + static void rtx_e1000_ring_init(${e1000::Ring.ref}, ${e1000::MMIO}, | |
404 + ${Builtin::number}, ${Builtin::number}); | |
405 + } | |
406 + | |
407 + chunk LKM::code() | |
408 + { | |
409 + static void rtx_e1000_ring_init(${e1000::Ring.ref} self, | |
410 + ${e1000::MMIO} io, | |
411 + ${Builtin::number} desc_count, | |
412 + ${Builtin::number} desc_size) | |
413 + { | |
414 + memset(self, 0, sizeof(*self)); | |
415 + self->size = ALIGN(desc_count * desc_size, 4096); | |
416 + self->io = io; | |
417 + } | |
418 + } | |
419 + | |
420 + method init(e1000::MMIO io, Builtin::number desc_count, Builtin::number desc_size) | |
421 + { | |
422 + rtx_e1000_ring_init(&${self}, ${io}, ${desc_count}, ${desc_size}); | |
423 } | |
424 | |
425 map | |
426 @@ -71,32 +324,27 @@ | |
427 } | |
428 } | |
429 | |
430 - /* | 173 - /* |
431 - * Ring of e1000::RxDescriptors and their corresponding skbuffs. | 174 - * Ring of e1000::RxDescriptors and their corresponding skbuffs. |
432 - * | 175 - * |
433 - * - size: total size of the ring in bytes. | 176 - * - size: total size of the ring in bytes. |
434 - * - base: address of the ring (we can't use the typedef here until we get | 177 - * - base: address of the ring (we can't use the typedef here until we get |
437 - * the different descriptors; | 180 - * the different descriptors; |
438 - * - skbuffs: array of the skbuffs and their dma (physical) address | 181 - * - skbuffs: array of the skbuffs and their dma (physical) address |
439 - * associated with each descriptor. | 182 - * associated with each descriptor. |
440 - */ | 183 - */ |
441 - template type e1000::RxRing() | 184 - template type e1000::RxRing() |
442 + template type e1000::RxRing() | 185 - { |
443 { | |
444 - decl data_types() | 186 - decl data_types() |
445 + decl data_types() | 187 - { |
446 { | |
447 - unsigned int size; | 188 - unsigned int size; |
448 - ${e1000::RxDescriptor.ref} base; | 189 - ${e1000::RxDescriptor.ref} base; |
449 - dma_addr_t dma_base; | 190 - dma_addr_t dma_base; |
450 - ${Socket::SKBuff} skbuffs[${config.rx_ring_size}]; | 191 - ${Socket::SKBuff} skbuffs[${config.rx_ring_size}]; |
451 + ${e1000::Ring} ring; | 192 - } |
452 } | 193 - |
453 | |
454 - method init() | 194 - method init() |
455 + chunk LKM::prototypes() | 195 - { |
456 { | 196 - } |
457 + static int rtx_e1000_alloc_rx_ressources(${e1000::RxRing.ref}); | 197 - |
458 } | |
459 | |
460 - chunk Ethernet::adapter_init_rx(Ethernet::Device rtx_ether_ctx) | 198 - chunk Ethernet::adapter_init_rx(Ethernet::Device rtx_ether_ctx) |
461 + chunk LKM::code() | 199 - { |
462 + { | 200 - { |
463 + static int rtx_e1000_alloc_rx_ressources(${e1000::RxRing.ref} self) | 201 - ${e1000::Context.ref} hw_ctx = &${rtx_ether_ctx}->hw_ctx; |
464 + { | 202 - |
465 + return 0; | 203 - /* |
466 + } | 204 - * Receive initialization (section 14.4): |
467 + } | 205 - * |
468 + | 206 - * 1. Program the receive address, in RAL/RAH; |
469 + chunk Ethernet::adapter_init_rx(Ethernet::Device rtx_ether_ctx) | 207 - * 2. Initialize the Multicast Table Array; |
470 { | 208 - * 3. Program the interrupt mask register (done in |
471 { | 209 - * e1000::activate_device_interruption); |
472 ${e1000::Context.ref} hw_ctx = &${rtx_ether_ctx}->hw_ctx; | 210 - * 4. Allocate the receive descriptor ring and map it to make it |
473 @@ -167,18 +415,16 @@ | 211 - * accessible by the device; |
474 * Allocate the skbuffs, map them for DMA, and write their address | 212 - * 5. Write the start address of the ring in RDBAL/RDBAH and set |
475 * in the corresponding descriptor. | 213 - * RDLEN (Receive Descriptor Length) to the size of the ring; |
476 */ | 214 - * 6. Set the RDH/RDT (Receive Descriptor Head/Tail) indexes to the |
215 - * beginning and end of the ring; | |
216 - * 7. Make sure that RCTL.BSIZE and .BSEX are at 0 to configure the | |
217 - * receive buffer size to 2048 bytes (e1000::rx_buffer_len). | |
218 - * 8. Set RCTL.EN to enable the receiver. | |
219 - * | |
220 - * The ugly casts here are caused by the lack of CNorm unstrict. | |
221 - */ | |
222 - | |
223 - int i; | |
224 - | |
225 - /* 1. Program the receive address */ | |
226 - | |
227 - /* (We should use uint{32,16}_t but CNorm doesn't know them yet) */ | |
228 - rtx_e1000_register_write32(hw_ctx, E1000_RAL, | |
229 - *(unsigned int *)(${rtx_ether_ctx.dev_addr})); | |
230 - /* | |
231 - * The 16 upper bits of RAH also store the AS bits (which should be | |
232 - * 0) and the AV bit (should be 1 to set the address as valid). | |
233 - */ | |
234 - rtx_e1000_register_write32(hw_ctx, E1000_RAH, | |
235 - *(unsigned short *)(&${rtx_ether_ctx.dev_addr}[4])); | |
236 - rtx_e1000_register_set32(hw_ctx, E1000_RAH, E1000_RAH_AV); | |
237 - | |
238 - ${Log::info("adapter_init_rx: receive address programmed")}; | |
239 - | |
240 - /* 2. Initialize the MTA */ | |
241 - | |
242 - for (i = 0; i != 128; ++i) | |
243 - rtx_e1000_register_write32(hw_ctx, E1000_MTA + i * 4, 0); | |
244 - | |
245 - ${Log::info("adapter_init_rx: MTA init done")}; | |
246 - | |
247 - /* 4. Setup the receive descriptor ring */ | |
248 - | |
249 - /* Allocate the descriptors */ | |
250 - hw_ctx->rx_ring.size = ${config.rx_ring_size} * sizeof(*hw_ctx->rx_ring.base); | |
251 - hw_ctx->rx_ring.size = ALIGN(hw_ctx->rx_ring.size, 4096); | |
252 - hw_ctx->rx_ring.base = ${DMA::alloc_coherent( | |
253 - rtx_ether_ctx.device, | |
254 - local.hw_ctx.rx_ring.size, | |
255 - local.hw_ctx.rx_ring.dma_base.dma_handle | |
256 - )}; | |
257 - if (!hw_ctx->rx_ring.base) | |
258 - { | |
259 - ${Log::info("adapter_init_rx: cannot allocate the descriptors for the rx ring")}; | |
260 - goto err_rx_ring_alloc; | |
261 - } | |
262 - | |
263 - ${Log::info("adapter_init_rx: rx descriptors allocated")}; | |
264 - | |
265 - /* | |
266 - * Allocate the skbuffs, map them for DMA, and write their address | |
267 - * in the corresponding descriptor. | |
268 - */ | |
477 - for (i = 0; i != ${config.rx_ring_size}; ++i) | 269 - for (i = 0; i != ${config.rx_ring_size}; ++i) |
478 - { | 270 - { |
479 + for (i = 0; i != ${config.rx_ring_size}; ++i) { | 271 - ${Socket::SKBuff.ref} skbuff = &hw_ctx->rx_ring.skbuffs[i]; |
480 ${Socket::SKBuff.ref} skbuff = &hw_ctx->rx_ring.skbuffs[i]; | |
481 - // XXX #46: ${rtx_ether_ctx.init_rx_skbuff(local.skbuff, config.rx_buffer_len)}; | 272 - // XXX #46: ${rtx_ether_ctx.init_rx_skbuff(local.skbuff, config.rx_buffer_len)}; |
482 - if (rtx_ethernet_init_rx_skbuff(${local.skbuff}, ${config.rx_buffer_len})) | 273 - if (rtx_ethernet_init_rx_skbuff(${local.skbuff}, ${config.rx_buffer_len})) |
483 - { | 274 - { |
484 + // XXX #46: ${rtx_ether_ctx.alloc_rx_skbuff(local.skbuff, config.rx_buffer_len)}; | 275 - ${Log::info("adapter_init_rx: cannot allocate a skbuff for the rx ring")}; |
485 + if (rtx_ethernet_alloc_rx_skbuff(${local.skbuff}, ${config.rx_buffer_len})) { | 276 - goto err_skbuffs_alloc; |
486 ${Log::info("adapter_init_rx: cannot allocate a skbuff for the rx ring")}; | 277 - } |
487 goto err_skbuffs_alloc; | |
488 } | |
489 - // XXX #46: ${local.skbuff.map_from(rtx_ether_ctx.device)}; | 278 - // XXX #46: ${local.skbuff.map_from(rtx_ether_ctx.device)}; |
490 - if (rtx_socket_skbuff_map(${local.skbuff}, ${rtx_ether_ctx.device}, RTX_DMA_FROM_DEVICE)) | 279 - if (rtx_socket_skbuff_map(${local.skbuff}, ${rtx_ether_ctx.device}, RTX_DMA_FROM_DEVICE)) |
491 - { | 280 - { |
492 + /* XXX: recuperer le dma handle et le placer correctement dans le descripteur. */ | 281 - ${Log::info("adapter_init_rx: cannot dma-map a skbuff for the rx ring")}; |
493 + ${DMA::map(local.rtx_ether_ctx.device, local.skbuff.data, local.skbuff.len, RTX_DMA_FROM_DEVICE)} | 282 - goto err_skbuffs_map; |
494 + if (${DMA::map(local.rtx_ether_ctx.device, local.skbuff.data, local.skbuff.len, RTX_DMA_FROM_DEVICE)}) { | 283 - } |
495 ${Log::info("adapter_init_rx: cannot dma-map a skbuff for the rx ring")}; | 284 - hw_ctx->rx_ring.base[i].buff_addr = cpu_to_le64(${local.skbuff.sk_buff}); |
496 goto err_skbuffs_map; | 285 - } |
497 } | 286 - |
498 @@ -212,8 +458,7 @@ | 287 - // ${Log::info("adapter_init_rx: skbuffs allocated}; |
499 goto init_rx_ok; | 288 - pr_info("rtx_e1k: adapter_init_rx: skbuffs allocated, headlen=%d", skb_headlen((struct sk_buff *)hw_ctx->rx_ring.skbuffs[i - 1].skbuff)); |
500 | 289 - |
501 err_skbuffs_alloc: | 290 - /* 5. Save the emplacement and the size of the ring in RDBA/RDLEN */ |
291 - rtx_e1000_register_write32(hw_ctx, E1000_RDBAL, hw_ctx->rx_ring.dma_base & 0xffffffff); | |
292 - rtx_e1000_register_write32(hw_ctx, E1000_RDBAH, hw_ctx->rx_ring.dma_base >> 32); | |
293 - rtx_e1000_register_write32(hw_ctx, E1000_RDLEN, hw_ctx->rx_ring.size); | |
294 - | |
295 - /* 6. Setup RDH/RDT */ | |
296 - rtx_e1000_register_write32(hw_ctx, E1000_RDH, 0); | |
297 - rtx_e1000_register_write32(hw_ctx, E1000_RDT, ${config.rx_ring_size} - 1); | |
298 - | |
299 - /* 7. Configure the buffer size, */ | |
300 - rtx_e1000_register_set32(hw_ctx, E1000_RCTL, E1000_RCTL_BSIZE_${config.rx_buffer_len}); | |
301 - | |
302 - /* 8. Enable the receiver */ | |
303 - rtx_e1000_register_set32(hw_ctx, E1000_RCTL, E1000_RCTL_EN); | |
304 - | |
305 - ${Log::info("adapter_init_rx: receive registers configured and receiver enabled")}; | |
306 - | |
307 - /* | |
308 - * XXX: We can't return here since we are not in a function but | |
309 - * in a chunk of code (injected in a function). | |
310 - */ | |
311 - goto init_rx_ok; | |
312 - | |
313 - err_skbuffs_alloc: | |
502 - while (i--) | 314 - while (i--) |
503 - { | 315 - { |
504 + while (i--) { | 316 - dma_unmap_single( |
505 dma_unmap_single( | 317 - ${rtx_ether_ctx.device}, |
506 ${rtx_ether_ctx.device}, | 318 - /* XXX Leaking cast because of the array: */ |
507 /* XXX Leaking cast because of the array: */ | 319 - *((dma_addr_t *)&(hw_ctx->rx_ring.skbuffs[i].dma_handle)), |
508 @@ -238,487 +483,87 @@ | 320 - ${config.rx_buffer_len}, |
509 } | 321 - DMA_FROM_DEVICE); |
510 } | 322 - err_skbuffs_map: |
511 | 323 - /* XXX leaking cast: */ |
324 - dev_kfree_skb((struct sk_buff *)hw_ctx->rx_ring.skbuffs[i].skbuff); | |
325 - } | |
326 - | |
327 - dma_free_coherent(${rtx_ether_ctx.device}, hw_ctx->rx_ring.size, | |
328 - hw_ctx->rx_ring.base, hw_ctx->rx_ring.dma_base); | |
329 - err_rx_ring_alloc: | |
330 - /* | |
331 - * XXX: Likewise, if there is something else to rollback in the | |
332 - * enclosing function, this won't be done. | |
333 - */ | |
334 - return -ENOMEM; | |
335 - | |
336 - init_rx_ok: (void)0; /* NOP, to make this a valid label. */ | |
337 - } | |
338 - } | |
339 - | |
512 - map | 340 - map |
513 + method init(e1000::MMIO io, Builtin::number desc_count) | 341 - { |
514 { | |
515 - size: ((${self}).size); | 342 - size: ((${self}).size); |
516 - dma_base: ((${self}).dma_base); | 343 - dma_base: ((${self}).dma_base); |
517 - } | 344 - } |
518 - } | 345 - } |
519 - | 346 - |
543 - ${e1000::TxDescriptor.ref} base; /* rename to descs */ | 370 - ${e1000::TxDescriptor.ref} base; /* rename to descs */ |
544 - dma_addr_t dma_base; | 371 - dma_addr_t dma_base; |
545 - ${Socket::SKBuff} skbuffs[${config.tx_ring_size}]; | 372 - ${Socket::SKBuff} skbuffs[${config.tx_ring_size}]; |
546 - unsigned short head; | 373 - unsigned short head; |
547 - unsigned short tail; | 374 - unsigned short tail; |
548 + ${self.ring.init(local.io, local.desc_count, self.desc_size)}; | 375 - } |
549 } | 376 - |
550 | |
551 - chunk LKM::prototypes() | 377 - chunk LKM::prototypes() |
552 + method alloc() | 378 - { |
553 { | |
554 - static void rtx_e1000_tx_ring_clean(${e1000::TxRing.ref}); | 379 - static void rtx_e1000_tx_ring_clean(${e1000::TxRing.ref}); |
555 - static unsigned int rtx_e1000_tx_ring_descriptors_remaining(${e1000::TxRing.ref}); | 380 - static unsigned int rtx_e1000_tx_ring_descriptors_remaining(${e1000::TxRing.ref}); |
556 - static int rtx_e1000_tx_ring_tso_cksum_offload(${e1000::TxRing.ref}, ${Socket::SKBuff.ref}); | 381 - static int rtx_e1000_tx_ring_tso_cksum_offload(${e1000::TxRing.ref}, ${Socket::SKBuff.ref}); |
557 - static void rtx_e1000_tx_ring_put(${e1000::TxRing.ref}, ${Socket::SKBuff.ref}); | 382 - static void rtx_e1000_tx_ring_put(${e1000::TxRing.ref}, ${Socket::SKBuff.ref}); |
558 - /* FIXME: See issue #54 */ | 383 - /* FIXME: See issue #54 */ |
705 - rtx_e1000_tx_ring_start_xmit(${self}, ${ctx}); | 530 - rtx_e1000_tx_ring_start_xmit(${self}, ${ctx}); |
706 - } | 531 - } |
707 - | 532 - |
708 - method init() | 533 - method init() |
709 - { | 534 - { |
710 + rtx_e1000_alloc_rx_ressources(${self}); | 535 - } |
711 } | 536 - |
712 | 537 - map |
713 map | 538 - { |
714 { | 539 - } |
715 + descs: ((${self})->descs); // TODO: fix cast pour directement avoir les descs | 540 - } |
716 + desc_size: sizeof(/* XXX ${e1000::RxDescriptor} */int); | 541 - |
717 } | |
718 } | |
719 | |
720 - template type e1000::Context() | 542 - template type e1000::Context() |
721 + template type e1000::TxRing() | 543 - { |
722 { | |
723 - decl data_types() | 544 - decl data_types() |
724 + decl data_types() | 545 - { |
725 { | |
726 - int bars; | 546 - int bars; |
727 - unsigned char /* __iomem */ *ioaddr; | 547 - unsigned char /* __iomem */ *ioaddr; |
728 - ${e1000::RxRing.scalar} rx_ring; | 548 - ${e1000::RxRing.scalar} rx_ring; |
729 - ${e1000::TxRing.scalar} tx_ring; | 549 - ${e1000::TxRing.scalar} tx_ring; |
730 + ${e1000::Ring} ring; | 550 - } |
731 } | 551 - |
732 | |
733 - chunk Ethernet::HardwareContext() | 552 - chunk Ethernet::HardwareContext() |
734 + chunk LKM::prototypes() | 553 - { |
735 { | |
736 - /* | 554 - /* |
737 - * Force the generation of the structure in the "headers" part, we | 555 - * Force the generation of the structure in the "headers" part, we |
738 - * have to do this since we do not use the structure in this blt | 556 - * have to do this since we do not use the structure in this blt |
739 - * (we hacked a bit and used it in ethernet.blt directly). | 557 - * (we hacked a bit and used it in ethernet.blt directly). |
740 - */ | 558 - */ |
741 - ${e1000::Context} hw_ctx; | 559 - ${e1000::Context} hw_ctx; |
742 + static int rtx_e1000_alloc_tx_ressources(${e1000::TxRing.ref}); | 560 - } |
743 } | 561 - |
744 | |
745 - chunk Ethernet::adapter_init_context(Ethernet::Device rtx_ether_ctx, | 562 - chunk Ethernet::adapter_init_context(Ethernet::Device rtx_ether_ctx, |
746 - Builtin::number bars, | 563 - Builtin::number bars, |
747 - Builtin::symbol ioaddr) | 564 - Builtin::symbol ioaddr) |
748 + chunk LKM::code() | 565 - { |
749 { | 566 - { |
750 + static int rtx_e1000_alloc_tx_ressources(${e1000::TxRing.ref} self) | |
751 { | |
752 - ${e1000::Context.ref} hw_ctx = &${rtx_ether_ctx}->hw_ctx; | 567 - ${e1000::Context.ref} hw_ctx = &${rtx_ether_ctx}->hw_ctx; |
753 - hw_ctx->bars = ${bars}; | 568 - hw_ctx->bars = ${bars}; |
754 - hw_ctx->ioaddr = ${ioaddr}; | 569 - hw_ctx->ioaddr = ${ioaddr}; |
755 + return 0; | 570 - } |
756 } | 571 - } |
757 } | 572 - |
758 | |
759 - chunk Ethernet::adapter_reset(Ethernet::Device rtx_ether_ctx) | 573 - chunk Ethernet::adapter_reset(Ethernet::Device rtx_ether_ctx) |
760 + method init(e1000::MMIO io, Builtin::number desc_count) | 574 - { |
761 { | |
762 - { | 575 - { |
763 - /* XXX Naming this variable 'hw_ctx' kicks the decl out of the generated code */ | 576 - /* XXX Naming this variable 'hw_ctx' kicks the decl out of the generated code */ |
764 - ${e1000::Context.ref} tmp_hw_ctx = &${rtx_ether_ctx}->hw_ctx; | 577 - ${e1000::Context.ref} tmp_hw_ctx = &${rtx_ether_ctx}->hw_ctx; |
765 - rtx_e1000_register_write32(tmp_hw_ctx, E1000_CTRL, E1000_CMD_RST); | 578 - rtx_e1000_register_write32(tmp_hw_ctx, E1000_CTRL, E1000_CMD_RST); |
766 - udelay(10); | 579 - udelay(10); |
767 - } | 580 - } |
768 + ${self.ring.init(local.io, local.desc_count, self.desc_size)}; | 581 - } |
769 } | 582 - |
770 | |
771 - chunk Ethernet::adapter_load_mac_address(Ethernet::Device rtx_ether_ctx) | 583 - chunk Ethernet::adapter_load_mac_address(Ethernet::Device rtx_ether_ctx) |
772 + method alloc() | 584 - { |
773 { | |
774 - { | 585 - { |
775 - ${e1000::Context.ref} hw_ctx = &${rtx_ether_ctx}->hw_ctx; | 586 - ${e1000::Context.ref} hw_ctx = &${rtx_ether_ctx}->hw_ctx; |
776 - /* Shamelessly borrowed from Minix */ | 587 - /* Shamelessly borrowed from Minix */ |
777 - for (int i = 0; i < 3; ++i) | 588 - for (int i = 0; i < 3; ++i) |
778 - { | 589 - { |
833 - for (int j = 0; j != 64; ++j) | 644 - for (int j = 0; j != 64; ++j) |
834 - rtx_e1000_register_write32(hw_ctx, E1000_CRCERRS + j * 4, 0); | 645 - rtx_e1000_register_write32(hw_ctx, E1000_CRCERRS + j * 4, 0); |
835 - | 646 - |
836 - ${Log::info("adapter_setup: general configuration done")}; | 647 - ${Log::info("adapter_setup: general configuration done")}; |
837 - } | 648 - } |
838 + rtx_e1000_alloc_tx_ressources(${self}); | 649 - } |
839 } | 650 - |
840 | 651 - map |
841 map | 652 - { |
842 { | |
843 - rx_ring: ((${self})->rx_ring); | 653 - rx_ring: ((${self})->rx_ring); |
844 - //tx_ring: ((${self})->tx_ring); XXX Circular dep with Context | 654 - //tx_ring: ((${self})->tx_ring); XXX Circular dep with Context |
845 + descs: ((${self})->descs); // TODO: fix cast pour directement avoir les descs | 655 - } |
846 + desc_size: sizeof(/* XXX ${e1000::TxDescriptor} */int); | 656 - } |
847 } | 657 - |
848 } | |
849 | |
850 - template type e1000::Register() | 658 - template type e1000::Register() |
851 + template type e1000::Context() | 659 - { |
852 { | |
853 - decl data_types() | 660 - decl data_types() |
854 + decl data_types() | 661 + decl data_types() |
855 { | 662 { |
856 - E1000_CTRL = 0x00000, /* Device Control - RW */ | 663 E1000_CTRL = 0x00000, /* Device Control - RW */ |
857 - E1000_CTRL_DUP = 0x00004, /* Device Control Duplicate (Shadow) - RW */ | 664 E1000_CTRL_DUP = 0x00004, /* Device Control Duplicate (Shadow) - RW */ |
858 - E1000_STATUS = 0x00008, /* Device Status - RO */ | 665 @@ -593,19 +37,14 @@ |
859 - E1000_EEPROM_FLASH = 0x00010, /* EEPROM/Flash Control - RW */ | 666 E1000_TDT = 0x03818, /* Transmit Descriptor Tail */ |
860 - E1000_EEPROM_READ = 0x00014, /* EEPROM Read - RW */ | |
861 - E1000_CTRL_EXT = 0x00018, /* Extended Device Control - RW */ | |
862 - E1000_FLA = 0x0001C, /* Flash Access - RW */ | |
863 - E1000_MDIC = 0x00020, /* MDI Control - RW */ | |
864 - E1000_IMS = 0x000D0, /* Interrupt Mask Set */ | |
865 - E1000_IMC = 0x000D8, /* Interrupt Mask Clear */ | |
866 - E1000_ICR = 0x000C0, /* Interrupt Cause Read - R/clr */ | |
867 - E1000_FCAL = 0x00028, /* Flow Control Address Low */ | |
868 - E1000_FCAH = 0x0002c, /* Flow Control Address High */ | |
869 - E1000_FCT = 0x00030, /* Flow Control Type */ | |
870 - E1000_RCTL = 0x00100, /* Receive Control */ | |
871 - E1000_FCTTV = 0x00170, /* Flow Control Transmit Timer Value */ | |
872 - E1000_TCTL = 0x00400, /* Transmit Control */ | |
873 - E1000_CRCERRS = 0x04000, /* CRC Error Count (base address of the statistic register spaces) */ | |
874 - E1000_RAL = 0x05400, /* Receive Address Low */ | |
875 - E1000_RAH = 0x05404, /* Receive Address High */ | |
876 - E1000_MTA = 0x05200, /* Multicast Table Array */ | |
877 - E1000_RDBAL = 0x02800, /* Receive Descriptor Base Address (Low 32 bits) */ | |
878 - E1000_RDBAH = 0x02804, /* Receive Descriptor Base Address (High 32 bits) */ | |
879 - E1000_RDLEN = 0x02808, /* Receive Descriptor Length */ | |
880 - E1000_RDH = 0x02810, /* Receive Descriptor Head */ | |
881 - E1000_RDT = 0x02818, /* Receive Descriptor Tail */ | |
882 - E1000_TDBAL = 0x03800, /* Transmit Descriptor Base Address (Low 32 bits) */ | |
883 - E1000_TDBAH = 0x03804, /* Transmit Descriptor Base Address (High 33 bits) */ | |
884 - E1000_TDLEN = 0x03808, /* Transmit Descriptor Length */ | |
885 - E1000_TDH = 0x03810, /* Transmit Descriptor Head */ | |
886 - E1000_TDT = 0x03818, /* Transmit Descriptor Tail */ | |
887 + ${e1000::MMIO} io; | |
888 + ${e1000::TxRing} tx_ring; | |
889 + ${e1000::RxRing} rx_ring; | |
890 } | 667 } |
891 | 668 |
892 - method init(Builtin::number value) | 669 - method init(Builtin::number value) |
893 + chunk LKM::includes() | 670 - { |
894 { | |
895 - ${self} = ${value}; | 671 - ${self} = ${value}; |
896 + #include <linux/types.h> | 672 - } |
897 } | 673 - |
898 | 674 map |
899 - map | 675 { |
900 - { | 676 } |
901 - } | 677 } |
902 - } | 678 |
903 - | |
904 - template type e1000::Commands() | 679 - template type e1000::Commands() |
905 - { | 680 + template type e1000::Command() |
681 { | |
906 - decl data_types() | 682 - decl data_types() |
907 - { | 683 + decl data_types() |
908 - E1000_CMD_FD = 0x00000001, /* Full duplex.0=half; 1=full */ | 684 { |
909 - E1000_CMD_BEM = 0x00000002, /* Endian Mode.0=little,1=big */ | 685 E1000_CMD_FD = 0x00000001, /* Full duplex.0=half; 1=full */ |
910 - E1000_CMD_PRIOR = 0x00000004, /* Priority on PCI. 0=rx,1=fair */ | 686 E1000_CMD_BEM = 0x00000002, /* Endian Mode.0=little,1=big */ |
911 - E1000_CMD_GIO_MASTER_DISABLE = 0x00000004, /* Blocks new Master requests */ | 687 @@ -670,9 +109,9 @@ |
912 - E1000_CMD_LRST = 0x00000008, /* Link reset. 0=normal,1=reset */ | 688 } |
913 - E1000_CMD_TME = 0x00000010, /* Test mode. 0=normal,1=test */ | 689 } |
914 - E1000_CMD_SLE = 0x00000020, /* Serial Link on 0=dis,1=en */ | 690 |
915 - E1000_CMD_ASDE = 0x00000020, /* Auto-speed detect enable */ | |
916 - E1000_CMD_SLU = 0x00000040, /* Set link up (Force Link) */ | |
917 - E1000_CMD_ILOS = 0x00000080, /* Invert Loss-Of Signal */ | |
918 - E1000_CMD_SPD_SEL = 0x00000300, /* Speed Select Mask */ | |
919 - E1000_CMD_SPD_10 = 0x00000000, /* Force 10Mb */ | |
920 - E1000_CMD_SPD_100 = 0x00000100, /* Force 100Mb */ | |
921 - E1000_CMD_SPD_1000 = 0x00000200, /* Force 1Gb */ | |
922 - E1000_CMD_BEM32 = 0x00000400, /* Big Endian 32 mode */ | |
923 - E1000_CMD_FRCSPD = 0x00000800, /* Force Speed */ | |
924 - E1000_CMD_FRCDPX = 0x00001000, /* Force Duplex */ | |
925 - E1000_CMD_D_UD_EN = 0x00002000, /* Dock/Undock enable */ | |
926 - E1000_CMD_D_UD_POLARITY = 0x00004000, /* Defined polarity of Dock/Undock indication in SDP[0] */ | |
927 - E1000_CMD_FORCE_PHY_RESET = 0x00008000, /* Reset both PHY ports, through PHYRST_N pin */ | |
928 - E1000_CMD_EXT_LINK_EN = 0x00010000, /* enable link status from external LINK_0 and LINK_1 pins */ | |
929 - E1000_CMD_SWDPIN0 = 0x00040000, /* SWDPIN 0 value */ | |
930 - E1000_CMD_SWDPIN1 = 0x00080000, /* SWDPIN 1 value */ | |
931 - E1000_CMD_SWDPIN2 = 0x00100000, /* SWDPIN 2 value */ | |
932 - E1000_CMD_SWDPIN3 = 0x00200000, /* SWDPIN 3 value */ | |
933 - E1000_CMD_SWDPIO0 = 0x00400000, /* SWDPIN 0 Input or output */ | |
934 - E1000_CMD_SWDPIO1 = 0x00800000, /* SWDPIN 1 input or output */ | |
935 - E1000_CMD_SWDPIO2 = 0x01000000, /* SWDPIN 2 input or output */ | |
936 - E1000_CMD_SWDPIO3 = 0x02000000, /* SWDPIN 3 input or output */ | |
937 - E1000_CMD_RST = 0x04000000, /* Global reset */ | |
938 - E1000_CMD_RFCE = 0x08000000, /* Receive Flow Control enable */ | |
939 - E1000_CMD_TFCE = 0x10000000, /* Transmit flow control enable */ | |
940 - E1000_CMD_RTE = 0x20000000, /* Routing tag enable */ | |
941 - E1000_CMD_VME = 0x40000000, /* IEEE VLAN mode enable */ | |
942 - E1000_CMD_PHY_RST = 0x80000000, /* PHY Reset */ | |
943 - E1000_CMD_SW2FW_INT = 0x02000000, /* Initiate an interrupt to manageability engine */ | |
944 - E1000_INTR_TXDW = 0x00000001, /* Transmit desc written back */ | |
945 - E1000_INTR_TXQE = 0x00000002, /* Transmit Queue empty */ | |
946 - E1000_INTR_LSC = 0x00000004, /* Link Status Change */ | |
947 - E1000_INTR_RXSEQ = 0x00000008, /* rx sequence error */ | |
948 - E1000_INTR_RXDMT0 = 0x00000010, /* rx desc min. threshold (0) */ | |
949 - E1000_INTR_RXO = 0x00000040, /* rx overrun */ | |
950 - E1000_INTR_RXT0 = 0x00000080, /* rx timer intr (ring 0) */ | |
951 - E1000_INTR_MDAC = 0x00000200, /* MDIO access complete */ | |
952 - E1000_RAH_AV = (1 << 31), /* Set the MAC Address as Valid */ | |
953 - E1000_RCTL_EN = (1 << 1), /* Receiver Enable */ | |
954 - E1000_RCTL_BSEX = (1 << 25), /* Buffer Size Extension */ | |
955 - E1000_RCTL_BSIZE_256 = ((1 << 16) | (1 << 17)), | |
956 - E1000_RCTL_BSIZE_512 = (1 << 17), | |
957 - E1000_RCTL_BSIZE_1024 = (1 << 16), | |
958 - E1000_RCTL_BSIZE_2048 = 0, | |
959 - E1000_RCTL_BSIZE_4096 = (E1000_RCTL_BSEX | (1 << 16) | (1 << 17)), | |
960 - E1000_RCTL_BSIZE_8192 = (E1000_RCTL_BSEX | (1 << 17)), | |
961 - E1000_RCTL_BSIZE_16384 = (E1000_RCTL_BSEX | (1 << 16)), | |
962 - E1000_TCTL_EN = (1 << 1), /* Transmitter Enable */ | |
963 - E1000_TCTL_PSP = (1 << 3), /* Pad Short Packet */ | |
964 - } | |
965 - | |
966 - map | |
967 - { | |
968 - } | |
969 - } | |
970 - | |
971 - template type e1000::TxDescriptorFlags() | 691 - template type e1000::TxDescriptorFlags() |
972 - { | 692 + template type e1000::TxDescriptorFlag() |
693 { | |
973 - decl data_types() | 694 - decl data_types() |
974 - { | 695 + decl data_types() |
975 - E1000_TXD_DTYP_D = 0x00100000, /* Data Descriptor */ | 696 { |
976 - E1000_TXD_DTYP_C = 0x00000000, /* Context Descriptor */ | 697 E1000_TXD_DTYP_D = 0x00100000, /* Data Descriptor */ |
977 - E1000_TXD_POPTS_IXSM = 0x01, /* Insert IP checksum */ | 698 E1000_TXD_DTYP_C = 0x00000000, /* Context Descriptor */ |
978 - E1000_TXD_POPTS_TXSM = 0x02, /* Insert TCP/UDP checksum */ | 699 @@ -701,326 +140,656 @@ |
979 - E1000_TXD_CMD_EOP = 0x01000000, /* End of Packet */ | 700 } |
980 - E1000_TXD_CMD_IFCS = 0x02000000, /* Insert FCS (Ethernet CRC) */ | 701 } |
981 - E1000_TXD_CMD_IC = 0x04000000, /* Insert Checksum */ | 702 |
982 - E1000_TXD_CMD_RS = 0x08000000, /* Report Status */ | |
983 - E1000_TXD_CMD_RPS = 0x10000000, /* Report Packet Sent */ | |
984 - E1000_TXD_CMD_DEXT = 0x20000000, /* Descriptor extension (0 = legacy) */ | |
985 - E1000_TXD_CMD_VLE = 0x40000000, /* Add VLAN tag */ | |
986 - E1000_TXD_CMD_IDE = 0x80000000, /* Enable Tidv register */ | |
987 - E1000_TXD_STAT_DD = 0x00000001, /* Descriptor Done */ | |
988 - E1000_TXD_STAT_EC = 0x00000002, /* Excess Collisions */ | |
989 - E1000_TXD_STAT_LC = 0x00000004, /* Late Collisions */ | |
990 - E1000_TXD_STAT_TU = 0x00000008, /* Transmit underrun */ | |
991 - E1000_TXD_CMD_TCP = 0x01000000, /* TCP packet */ | |
992 - E1000_TXD_CMD_IP = 0x02000000, /* IP packet */ | |
993 - E1000_TXD_CMD_TSE = 0x04000000, /* TCP Seg enable */ | |
994 - E1000_TXD_STAT_TC = 0x00000004, /* Tx Underrun */ | |
995 - } | |
996 - | |
997 - map | |
998 - { | |
999 - } | |
1000 - } | |
1001 - | |
1002 - /* TODO: make that a method of e1000::Context */ | 703 - /* TODO: make that a method of e1000::Context */ |
1003 - template sequence e1000::print_status(Ethernet::Device rtx_ether_ctx) | 704 - template sequence e1000::print_status(Ethernet::Device rtx_ether_ctx) |
1004 - { | 705 + template type e1000::RxDescriptor() |
706 { | |
1005 - chunk LKM::prototypes() | 707 - chunk LKM::prototypes() |
708 + decl data_types() | |
709 + { | |
710 + __le64 buff_addr; | |
711 + __le16 length; | |
712 + __le16 csum; | |
713 + unsigned char status; | |
714 + unsigned char errors; | |
715 + __le16 special; | |
716 + } | |
717 + | |
718 + map | |
719 + { | |
720 + } | |
721 + } | |
722 + | |
723 + // This is a generic tx descriptor for the e1000. When you use TCP | |
724 + // Segmentation Offload (TSO) the hardware actually uses two types of | |
725 + // tx descriptors in its tx ring: | |
726 + // - context descriptors: this descriptor doesn't actually point to data to | |
727 + // send but initialize the offloading engine for the data descriptor that | |
728 + // follow; | |
729 + // - data descriptors: this descriptor points to data from the skbuffs. | |
730 + template type e1000::TxDescriptor() | |
731 + { | |
732 + decl data_types() | |
733 + { | |
734 + __le64 buff_addr; | |
735 + union { | |
736 + __le32 data; | |
737 + struct { | |
738 + __le16 length; | |
739 + unsigned char csum_offset; /* CSO */ | |
740 + unsigned char cmd; | |
741 + } fields; | |
742 + } lower; | |
743 + union { | |
744 + __le32 data; | |
745 + struct { | |
746 + unsigned char status; | |
747 + unsigned char csum_start; /* CSS */ | |
748 + __le16 special; | |
749 + } fields; | |
750 + } upper; | |
751 + } | |
752 + | |
753 + map | |
754 + { | |
755 + } | |
756 + } | |
757 + | |
758 + template type e1000::Buffer() | |
759 + { | |
760 + decl data_types() | |
761 + { | |
762 + ${Socket::SKBuff} sk_buff; | |
763 + ${DMA::DMAHandle} dma; | |
764 + } | |
765 + | |
766 + method init(Socket::SKBuff sk_buff, DMA::DMAHandle dma) | |
767 + { | |
768 + ${self.sk_buff} = ${sk_buff}; | |
769 + ${self.dma} = ${dma}; | |
770 + } | |
771 + | |
772 + map | |
773 + { | |
774 + sk_buff: ${self}->sk_buff; | |
775 + dma: ${self}->dma; | |
776 + } | |
777 + } | |
778 + | |
779 + template type e1000::Context() | |
780 + { | |
781 + decl data_types() | |
782 + { | |
783 + unsigned char *io_addr; // XXX should be annoted with __iomem | |
784 + // XXX Forced to hardcode the type because there is a circular | |
785 + // dependency between the rings and the context. | |
786 + // TODO: get the right generated types: | |
787 + int tx_ring; | |
788 + int rx_ring; | |
789 + } | |
790 + | |
791 + chunk LKM::includes() | |
792 + { | |
793 + #include <linux/types.h> | |
794 + } | |
795 + | |
1006 + chunk LKM::prototypes() | 796 + chunk LKM::prototypes() |
1007 { | 797 { |
1008 static void rtx_e1000_print_status(${e1000::Context.ref}); | 798 static void rtx_e1000_print_status(${e1000::Context.ref}); |
799 + | |
800 + // XXX Needed until we can call methods (issue #46): | |
801 + static unsigned int rtx_e1000_reg_read32(${e1000::Context}, ${e1000::Register}); | |
802 + static void rtx_e1000_reg_write32(${e1000::Context}, ${e1000::Register}, unsigned int); | |
803 + static void rtx_e1000_reg_set32(${e1000::Context}, ${e1000::Register}, unsigned int); | |
804 + static void rtx_e1000_reg_unset32(${e1000::Context}, ${e1000::Register}, unsigned int); | |
1009 } | 805 } |
1010 | 806 |
1011 - chunk LKM::code() | 807 - chunk LKM::code() |
1012 + chunk LKM::code() | 808 + chunk LKM::code() |
1013 { | 809 { |
1014 static void rtx_e1000_print_status(${e1000::Context.ref} hw_ctx) | 810 - static void rtx_e1000_print_status(${e1000::Context.ref} hw_ctx) |
811 + static void rtx_e1000_print_status(${e1000::Context.ref} self) | |
1015 { | 812 { |
1016 - unsigned int status = rtx_e1000_register_read32(hw_ctx, E1000_STATUS); | 813 - unsigned int status = rtx_e1000_register_read32(hw_ctx, E1000_STATUS); |
1017 - ${Log::info("card status:")}; | 814 - ${Log::info("card status:")}; |
1018 - /* | 815 - /* |
1019 - * we can't use Log::info below because it just accept a string | 816 - * we can't use Log::info below because it just accept a string |
1020 - * (as opposed to a format string with its parameters). | 817 - * (as opposed to a format string with its parameters). |
1021 - */ | 818 - */ |
1022 + unsigned int status = rtx_e1000_reg_read32(hw_ctx, E1000_STATUS); | 819 + unsigned int status = rtx_e1000_reg_read32(${local.self}, E1000_STATUS); |
1023 + ${Log::info("card status:")}; | 820 + ${Log::info("card status:")}; |
1024 + // XXX We can't use Log::info below because it just accept a | 821 + // XXX We can't use Log::info below because it just accepts a |
1025 + // string (as opposed to a format string with its parameters): | 822 + // string (as opposed to a format string with its arguments): |
1026 pr_info("\tRegister value: 0x%x\n", status); | 823 pr_info("\tRegister value: 0x%x\n", status); |
1027 pr_info("\tMode: %s\n", (status & 1) ? "Full": "Half"); | 824 pr_info("\tMode: %s\n", (status & 1) ? "Full": "Half"); |
1028 pr_info("\tLink: %s\n", (status & 2) ? "Up" : "Down"); | 825 pr_info("\tLink: %s\n", (status & 2) ? "Up" : "Down"); |
1029 @@ -727,300 +572,178 @@ | 826 pr_info("\tTransmission: %s\n", (status & 4) ? "Paused" : "Ok"); |
827 pr_info("\tInterface: %s\n", (status & 3) == 3 ? "Up" : "Down"); | |
1030 } | 828 } |
829 + | |
830 + static unsigned int rtx_e1000_reg_read32(${e1000::Context} self, ${e1000::Register} reg) | |
831 + { | |
832 + return ioread32(${local.self.io_addr} + reg); | |
833 + } | |
834 + | |
835 + static void rtx_e1000_reg_write32(${e1000::Context} self, | |
836 + ${e1000::Register} reg, | |
837 + unsigned int value) | |
838 + { | |
839 + return iowrite32(value, ${local.self.io_addr.io} + reg); | |
840 + } | |
841 + | |
842 + static void rtx_e1000_reg_set32(${e1000::Context} self, | |
843 + ${e1000::Register} reg, | |
844 + unsigned int value) | |
845 + { | |
846 + return iowrite32( | |
847 + rtx_e1000_reg_read32(${local.self}, reg) | value, | |
848 + ${local.self.io_addr.io} + reg | |
849 + ); | |
850 + } | |
851 + | |
852 + static void rtx_e1000_reg_unset32(${e1000::Context} self, | |
853 + ${e1000::Register} reg, | |
854 + unsigned int value) | |
855 + { | |
856 + return iowrite32(rtx_e1000_reg_read32( | |
857 + ${local.self}, reg) & ~value, | |
858 + ${local.self.io_addr.io} + reg | |
859 + ); | |
860 + } | |
1031 } | 861 } |
1032 | 862 |
1033 - chunk ::CALL() | 863 - chunk ::CALL() |
864 + method init(Builtin::symbol io_addr) | |
865 { | |
866 - rtx_e1000_print_status(&${rtx_ether_ctx}->hw_ctx); | |
867 + ${self.io_addr} = ${io_addr}; | |
868 + } | |
869 + | |
870 + method reg_read32(e1000::Register reg) | |
871 + { | |
872 + ioread32(${self.io_addr} + ${local.reg}); | |
873 + } | |
874 + | |
875 + method reg_write32(e1000::Register reg, Builtin::number value) | |
876 + { | |
877 + iowrite32(${value}, ${self.io_addr} + ${reg}); | |
878 + } | |
879 + | |
880 + method reg_set32(e1000::Register reg, Builtin::number value) | |
881 + { | |
882 + iowrite32(ioread32(${self.io_addr} + ${reg}) | ${value}, ${self.io_addr} + ${reg}); | |
883 + } | |
884 + | |
885 + method reg_unset32(e1000::Register reg, Builtin::number value) | |
886 + { | |
887 + iowrite32(ioread32(${self.io_addr} + ${reg}) & ~${value}, ${self.io_addr} + ${reg}); | |
888 + } | |
889 + | |
1034 + chunk Ethernet::HardwareContext() | 890 + chunk Ethernet::HardwareContext() |
1035 { | 891 + { |
1036 - rtx_e1000_print_status(&${rtx_ether_ctx}->hw_ctx); | 892 + ${e1000::Context} hw_ctx; |
1037 - } | 893 + } |
1038 - } | 894 + |
1039 - | 895 + chunk Ethernet::adapter_init_context(Ethernet::Device rtx_ether_ctx, Builtin::symbol io_addr) |
896 + { | |
897 + { | |
898 + ${e1000::Context.ref} hw_ctx = &${local.rtx_ether_ctx}->hw_ctx; | |
899 + ${local.hw_ctx.init(local.io_addr)}; | |
900 + ${local.hw_ctx.rx_ring.init(local.hw_ctx.io, config.rx_ring_size)}; | |
901 + ${local.hw_ctx.tx_ring.init(local.hw_ctx.io, config.tx_ring_size)}; | |
902 + } | |
903 + } | |
904 + | |
905 + chunk Ethernet::adapter_reset(Ethernet::Device rtx_ether_ctx) | |
906 + { | |
907 + { | |
908 + ${e1000::Context.ref} hw_ctx = &${local.rtx_ether_ctx}->hw_ctx; | |
909 + // XXX #46: ${local.hw_ctx.io.write32(E1000_CTRL, E1000_CMD_RST)}; | |
910 + rtx_e1000_reg_write32(hw_ctx, E1000_CTRL, E1000_CMD_RST); | |
911 + udelay(10); // TODO: abstract udelay too... | |
912 + ${Log::info("adapter has been reset")}; | |
913 + } | |
914 + } | |
915 + | |
916 + chunk Ethernet::adapter_load_mac_address(Ethernet::Device rtx_ether_ctx) | |
917 + { | |
918 + { | |
919 + ${e1000::Context.ref} hw_ctx = &${local.rtx_ether_ctx}->hw_ctx; | |
920 + // Shamelessly borrowed from Minix | |
921 + for (int i = 0; i < 3; ++i) { | |
922 + rtx_e1000_reg_write32(hw_ctx, E1000_EEPROM_READ, (i << 8) | 1); | |
923 + int value; | |
924 + do { | |
925 + value = rtx_e1000_reg_read32(hw_ctx, E1000_EEPROM_READ); | |
926 + } while ((value & (1 << 4)) == 0); | |
927 + value >>= 16; | |
928 + // NOTE: I'm not sure if Ethernet::Device should be | |
929 + // accessed directly here. But since we need to take it in | |
930 + // parameter (so we can get back our e1000::Context) it | |
931 + // seems inadequate to set this in another way: | |
932 + ${local.rtx_ether_ctx.dev_addr}[i * 2] = value & 0xff; | |
933 + ${local.rtx_ether_ctx.dev_addr}[i * 2 + 1] = (value >> 8) & 0xff; | |
934 + } | |
935 + | |
936 + ${Log::info("mac address loaded from the EEPROM")}; | |
937 + } | |
938 + } | |
939 + | |
940 + // For e1000, this part is documented in the Intel Gigabit Ethernet | |
941 + // Controller Software Developper manual. (You can find it in the | |
942 + // doc/hardware directory). | |
943 + chunk Ethernet::adapter_setup_rx_tx(Ethernet::Device rtx_ether_ctx) | |
944 + { | |
945 + { | |
946 + ${e1000::Context.ref} hw_ctx = &${local.rtx_ether_ctx}->hw_ctx; | |
947 + | |
948 + // "General Configuration" (section 14.3): | |
949 + // | |
950 + // - CTRL.ASDE/CTRL.SLU: Let the PHY handle the speed detection & | |
951 + // negociation; | |
952 + // - CTRL.LRST/FRCSPD: Unset them to initiate the auto-negociation; | |
953 + // - CTRL.PHY_RST: Unset it; | |
954 + // - CTRL.ILOS: Unset it (ILOS is Invert Loss Of Signal); | |
955 + // - CTRL.VME: Make sure it's not set to disable VLAN support; | |
956 + // - Set the control flow registers to 0; | |
957 + // - Finally, initialize all the statistic registers from | |
958 + // E1000_CRCERRS to E1000_TSCTFC. | |
959 + | |
960 + // XXX #46: Use the read/write/set/unset methods on Context | |
961 + rtx_e1000_reg_set32(hw_ctx, E1000_CTRL, E1000_CMD_ASDE|E1000_CMD_SLU); | |
962 + rtx_e1000_reg_unset32( | |
963 + hw_ctx, | |
964 + E1000_CTRL, | |
965 + E1000_CMD_LRST|E1000_CMD_FRCSPD|E1000_CMD_PHY_RST| | |
966 + E1000_CMD_ILOS|E1000_CMD_VME | |
967 + ); | |
968 + rtx_e1000_reg_write32(hw_ctx, E1000_FCAH, 0); | |
969 + rtx_e1000_reg_write32(hw_ctx, E1000_FCAL, 0); | |
970 + rtx_e1000_reg_write32(hw_ctx, E1000_FCT, 0); | |
971 + rtx_e1000_reg_write32(hw_ctx, E1000_FCTTV, 0); | |
972 + for (int i = 0; i != 64; ++i) | |
973 + rtx_e1000_reg_write32(hw_ctx, E1000_CRCERRS + i * 4, 0); | |
974 + | |
975 + ${Log::info("adapter_setup_rx_tx: general configuration done")}; | |
976 + | |
977 + int err; | |
978 + | |
979 + err = rtx_e1000_rx_ring_alloc_resources(&hw_ctx->rx_ring); | |
980 + if (err) | |
981 + goto err_alloc_rx_ring; | |
982 + rtx_e1000_rx_ring_configure(&hw_ctx->rx_ring); | |
983 + | |
984 + err = rtx_e1000_tx_ring_alloc_resources(&hw_ctx->tx_ring); | |
985 + if (err) | |
986 + goto err_alloc_tx_ring; | |
987 + rtx_e1000_tx_ring_configure(&hw_ctx->tx_ring); | |
988 + | |
989 + err_alloc_tx_ring: | |
990 + rtx_e1000_rx_ring_free_resources(&hw_ctx->rx_ring); | |
991 + err_alloc_rx_ring: | |
992 + // XXX Can't return here since we don't know the context. | |
993 + // TODO: hardcode a goto | |
994 + (void)1; | |
995 + } | |
996 + } | |
997 + | |
998 + chunk Ethernet::adapter_enable_interrupts(Ethernet::Device) | |
999 + { | |
1000 + { | |
1001 + ${e1000::Context.ref} hw_ctx = &${local.rtx_ether_ctx}->hw_ctx; | |
1002 + rtx_e1000_reg_write32( | |
1003 + hw_ctx, | |
1004 + E1000_IMS, | |
1005 + E1000_INTR_TXDW|E1000_INTR_TXQE|E1000_INTR_LSC| | |
1006 + E1000_INTR_RXO|E1000_INTR_RXT0 | |
1007 + ); | |
1008 + | |
1009 + // XXX We should probably move that elsewhere (it just used to | |
1010 + // be done right after we enabled interrupts when this was | |
1011 + // still in lkm.rtx): | |
1012 + // XXX #46: ${local.hw_ctx.print_status()}; | |
1013 + rtx_e1000_print_status(hw_ctx); | |
1014 + } | |
1015 + } | |
1016 + | |
1017 + chunk Ethernet::disable_interrupts(Ethernet::Device rtx_ether_ctx) | |
1018 + { | |
1019 + { ${Log::info("adapter_disable_interrupts: TBD...")}; } | |
1020 + } | |
1021 + | |
1022 + chunk Ethernet::adapter_handle_interrupt(Ethernet::Device rtx_ether_ctx) | |
1023 + { | |
1024 + { | |
1025 + ${e1000::Context.ref} hw_ctx = &${local.rtx_ether_ctx}->hw_ctx; | |
1026 + unsigned int icr = rtx_e1000_reg_read32(hw_ctx, E1000_ICR); | |
1027 + pr_info("%s: interrupt received, ICR: 0x%x", ${config.name}, icr); | |
1028 + if (icr) { | |
1029 + if (icr & E1000_INTR_LSC) { | |
1030 + ${Log::info("handle_interrupt: cable link status changed, dumping card status:")}; | |
1031 + // XXX #46: ${local.hw_ctx.print_status()}; | |
1032 + rtx_e1000_print_status(hw_ctx); | |
1033 + } | |
1034 + if (icr & (E1000_INTR_TXQE|E1000_INTR_TXDW)) { | |
1035 + ${Log::info("handle_interrupt: TxRing: packet(s) sent")}; | |
1036 + } | |
1037 + if (icr & E1000_INTR_RXT0) { | |
1038 + ${Log::info("handle_interrupt: RxRing: packet(s) received")}; | |
1039 + } | |
1040 + if (icr & E1000_INTR_RXO) { | |
1041 + ${Log::info("handle_interrupt: RxRing: overrun")}; | |
1042 + } | |
1043 + | |
1044 + // XXX: This sucks since we don't know the pointcut context: | |
1045 + return IRQ_HANDLED; | |
1046 + } | |
1047 + } | |
1048 + } | |
1049 + | |
1050 + chunk Ethernet::adapter_xmit(Ethernet::Device rtx_ether_ctx, Socket::SKBuff rtx_skb) | |
1051 + { | |
1052 + { ${Log::info("adapter_xmit: TBD...")}; } | |
1053 + } | |
1054 + | |
1055 + chunk Ethernet::adapter_disable_rx(Ethernet::Device rtx_ether_ctx) | |
1056 + { | |
1057 + { ${Log::info("adapter_disable_rx: TBD..")}; } | |
1058 + } | |
1059 + | |
1060 + chunk Ethernet::adpater_disable_tx(Ethernet::Device rtx_ether_ctx) | |
1061 + { | |
1062 + { ${Log::info("adapter_disable_tx: TBD..")}; } | |
1063 + } | |
1064 + | |
1065 + chunk Ethernet::adapter_free_rx_tx(Ethernet::Device rtx_ether_ctx) | |
1066 + { | |
1067 + { ${Log::info("adapter_free_rx_tx: TBD..")}; } | |
1068 + } | |
1069 + | |
1070 + method print_status() | |
1071 + { | |
1072 + rtx_e1000_print_status(${self}); | |
1073 + } | |
1074 + | |
1075 + map | |
1076 + { | |
1077 + io_addr: ${self}->io; | |
1078 + rx_ring: ${self}->rx_ring; | |
1079 + tx_ring: ${self}->tx_ring; | |
1080 } | |
1081 } | |
1082 | |
1040 - /* | 1083 - /* |
1041 - * We should have been able to do something along those lines, but | 1084 - * We should have been able to do something along those lines, but |
1042 - * it didn't work so we made the call manually. | 1085 - * it didn't work so we made the call manually. |
1043 - * | 1086 - * |
1044 - * Ideally: | 1087 - * Ideally: |
1054 - * ${e1000::register_read32(rtx_ether_ctx->hw_ctx, reg_status)}; | 1097 - * ${e1000::register_read32(rtx_ether_ctx->hw_ctx, reg_status)}; |
1055 - * | 1098 - * |
1056 - * TODO: make them methods of e1000::Context | 1099 - * TODO: make them methods of e1000::Context |
1057 - */ | 1100 - */ |
1058 - template sequence e1000::register_read32(e1000::Context ctx, e1000::Register reg_offset) | 1101 - template sequence e1000::register_read32(e1000::Context ctx, e1000::Register reg_offset) |
1059 - { | 1102 + template type e1000::Ring() |
1103 { | |
1060 - chunk LKM::prototypes() | 1104 - chunk LKM::prototypes() |
1061 - { | 1105 + decl data_types() |
1106 { | |
1062 - /* FIXME: See issue #54 */ | 1107 - /* FIXME: See issue #54 */ |
1063 - static unsigned int rtx_e1000_register_read32(/*const*/ ${e1000::Context.ref}, unsigned int); | 1108 - static unsigned int rtx_e1000_register_read32(/*const*/ ${e1000::Context.ref}, unsigned int); |
1064 + ${e1000::Context} hw_ctx; | 1109 + ${e1000::Context} hw_ctx; |
1110 + ${DMA::DMAHandle} dma; | |
1111 + unsigned int size; | |
1112 + ${Builtin::symbol.ref} descs; | |
1113 + ${e1000::Buffer.ref} buffs; | |
1065 } | 1114 } |
1066 | 1115 |
1067 - chunk LKM::code() | 1116 - chunk LKM::code() |
1068 + chunk Ethernet::adapter_init_context(Ethernet::Device rtx_ether_ctx, Builtin::symbol ioaddr) | 1117 + chunk LKM::prototypes() |
1069 { | 1118 { |
1070 - /* FIXME: See issue #54 */ | 1119 - /* FIXME: See issue #54 */ |
1071 - static unsigned int rtx_e1000_register_read32(/*const*/ ${e1000::Context.ref} ctx, unsigned int reg_offset) | 1120 - static unsigned int rtx_e1000_register_read32(/*const*/ ${e1000::Context.ref} ctx, unsigned int reg_offset) |
1121 + static void rtx_e1000_ring_init(${e1000::Ring.ref}, ${e1000::Context}, int, int); | |
1122 + } | |
1123 + | |
1124 + chunk LKM::code() | |
1125 + { | |
1126 + static void rtx_e1000_ring_init(${e1000::Ring.ref} self, ${e1000::Context} hw_ctx, | |
1127 + int desc_count, int desc_size) | |
1072 { | 1128 { |
1073 - return ioread32(ctx->ioaddr + reg_offset); | 1129 - return ioread32(ctx->ioaddr + reg_offset); |
1074 + ${e1000::Context.ref} hw_ctx = &${local.rtx_ether_ctx}->hw_ctx; | 1130 + BUG_ON(desc_count <= 0 || desc_size <= 0); |
1075 + ${local.hw_ctx.io.init(local.ioaddr)}; | 1131 + memset(self, 0, sizeof(*self)); |
1076 + ${local.hw_ctx.rx_ring.init(local.hw_ctx.io, config.rx_ring_size)}; | 1132 + self->size = ALIGN(desc_count * desc_size, 4096); |
1077 + ${local.hw_ctx.tx_ring.init(local.hw_ctx.io, config.tx_ring_size)}; | 1133 + self->hw_ctx = hw_ctx; |
1078 } | 1134 } |
1079 } | 1135 } |
1080 | 1136 |
1081 - chunk ::CALL() | 1137 - chunk ::CALL() |
1082 + chunk Ethernet::adapter_reset(Ethernet::Device rtx_ether_ctx) | 1138 + method init(e1000::Context hw_ctx, Builtin::number desc_count, Builtin::number desc_size) |
1083 { | 1139 { |
1084 - rtx_e1000_register_read32(${ctx}, ${reg_offset}); | 1140 - rtx_e1000_register_read32(${ctx}, ${reg_offset}); |
1085 - } | 1141 + rtx_e1000_ring_init(&${self}, ${hw_ctx}, ${desc_count}, ${desc_size}); |
1086 - } | 1142 + } |
1087 - | 1143 + |
1144 + map | |
1145 + { | |
1146 + hw_ctx: ${self}->hw_ctx; | |
1147 + dma: ${self}->dma; | |
1148 + size: ${self}->size; | |
1149 + descs: ${self}->descs; | |
1150 + buffs: ${self}->buffs; | |
1151 } | |
1152 } | |
1153 | |
1088 - template sequence e1000::register_write32(e1000::Context ctx, e1000::Register reg_offset, ::number value) | 1154 - template sequence e1000::register_write32(e1000::Context ctx, e1000::Register reg_offset, ::number value) |
1089 - { | 1155 + template type e1000::RxRing() |
1156 { | |
1090 - chunk LKM::prototypes() | 1157 - chunk LKM::prototypes() |
1091 - { | 1158 + decl data_types() |
1159 { | |
1092 - /* FIXME: See issue #54 */ | 1160 - /* FIXME: See issue #54 */ |
1093 - static void rtx_e1000_register_write32(/*const*/ ${e1000::Context.ref}, unsigned int, unsigned int); | 1161 - static void rtx_e1000_register_write32(/*const*/ ${e1000::Context.ref}, unsigned int, unsigned int); |
1094 - } | 1162 + ${e1000::Ring} ring; |
1095 - | 1163 } |
1164 | |
1096 - chunk LKM::code() | 1165 - chunk LKM::code() |
1097 - { | 1166 + chunk LKM::prototypes() |
1167 { | |
1098 - /* FIXME: See issue #54 */ | 1168 - /* FIXME: See issue #54 */ |
1099 - static void rtx_e1000_register_write32(/*const*/ ${e1000::Context.ref} ctx, unsigned int reg_offset, unsigned int value) | 1169 - static void rtx_e1000_register_write32(/*const*/ ${e1000::Context.ref} ctx, unsigned int reg_offset, unsigned int value) |
1170 + static int rtx_e1000_rx_ring_alloc_resources(${e1000::RxRing.ref}); | |
1171 + static void rtx_e1000_rx_ring_configure(${e1000::RxRing.ref}); | |
1172 + } | |
1173 + | |
1174 + chunk LKM::code() | |
1175 + { | |
1176 + static int rtx_e1000_rx_ring_alloc_resources(${e1000::RxRing.ref} self) | |
1100 { | 1177 { |
1101 - iowrite32(value, ctx->ioaddr + reg_offset); | 1178 - iowrite32(value, ctx->ioaddr + reg_offset); |
1102 + ${e1000::Context.ref} hw_ctx = &${local.rtx_ether_ctx}->hw_ctx; | 1179 + // XXX Reread & Fix everything down there (data structure changes and so on) |
1103 + // XXX #46: ${local.hw_ctx.io.write32(E1000_CTRL, E1000_CMD_RST)}; | 1180 + |
1104 + rtx_e1000_reg_write32(hw_ctx, E1000_CTRL, E1000_CMD_RST); | 1181 + // 4. Setup the receive descriptor ring |
1105 + udelay(10); // TODO: abstract this too... | 1182 + |
1106 + ${Log::info("adapter has been reset")}; | 1183 + int i; |
1184 + | |
1185 + // Allocate the descriptors | |
1186 + hw_ctx->rx_ring.base = ${DMA::alloc_coherent( | |
1187 + local.self.hw_ctx.net_dev.device, local.self.size, | |
1188 + local.self.dma.dma_handle | |
1189 + )}; | |
1190 + if (!hw_ctx->rx_ring.base) { | |
1191 + ${Log::info("adapter_init_rx: cannot allocate the descriptors for the rx ring")}; | |
1192 + goto err_rx_ring_alloc; | |
1193 + } | |
1194 + | |
1195 + ${Log::info("adapter_init_rx: rx descriptors allocated")}; | |
1196 + | |
1197 + // Allocate the skbuffs, map them for DMA, and write their address | |
1198 + // in the corresponding descriptor. | |
1199 +// for (i = 0; i != ${config.rx_ring_size}; ++i) { | |
1200 +// ${Socket::SKBuff.ref} skbuff = &hw_ctx->rx_ring.skbuffs[i]; | |
1201 +// // XXX #46: ${rtx_ether_ctx.alloc_rx_skbuff(local.skbuff, config.rx_buffer_len)}; | |
1202 +// if (rtx_ethernet_alloc_rx_skbuff(ocal.skbuff, ${config.rx_buffer_len})) { | |
1203 +// ${Log::info("adapter_init_rx: cannot allocate a skbuff for the rx ring")}; | |
1204 +// goto err_skbuffs_alloc; | |
1205 +// } | |
1206 +// /* TODO: recuperer le dma handle et le placer correctement dans le descripteur. */ | |
1207 +// ${DMA::map(local.rtx_ether_ctx.device, local.skbuff.data, local.skbuff.len, RTX_DMA_FROM_DEVICE)} | |
1208 +// if (${DMA::map(local.rtx_ether_ctx.device, local.skbuff.data, local.skbuff.len, RTX_DMA_FROM_DEVICE)}) { | |
1209 +// ${Log::info("adapter_init_rx: cannot dma-map a skbuff for the rx ring")}; | |
1210 +// goto err_skbuffs_map; | |
1211 +// } | |
1212 +// hw_ctx->rx_ring.base[i].buff_addr = cpu_to_le64(${local.skbuff.sk_buff}); | |
1213 +// } | |
1214 + | |
1215 + // ${Log::info("adapter_init_rx: skbuffs allocated}; | |
1216 + pr_info("rtx_e1k: adapter_init_rx: skbuffs allocated, headlen=%d", skb_headlen((struct sk_buff *)hw_ctx->rx_ring.skbuffs[i - 1].skbuff)); | |
1217 + | |
1218 + err_skbuffs_alloc: | |
1219 + while (i--) { | |
1220 + ${DMA::unmap( | |
1221 + local.self.hw_ctx.net_dev.device, | |
1222 + // XXX Leaking cast because of the array: (TODO: the data structure changed) | |
1223 + *((dma_addr_t *)&(self->buffs[i].dma_handle)), | |
1224 + ${config.rx_buffer_len}, | |
1225 + RTX_DMA_FROM_DEVICE | |
1226 + )}; | |
1227 + err_skbuffs_map: | |
1228 + // XXX leaking cast: (TODO: the data structure changed) | |
1229 + dev_kfree_skb((struct sk_buff *)hw_ctx->rx_ring.skbuffs[i].skbuff); | |
1230 + } | |
1231 + | |
1232 + ${DMA::free_coherent( | |
1233 + local.self.hw_ctx.net_dev.device, local.self.size, | |
1234 + local.self.descs, local.self.dma.dma_handle | |
1235 + )}; | |
1236 + err_rx_ring_alloc: | |
1237 + return -ENOMEM; | |
1238 + } | |
1239 + | |
1240 + static void rtx_e1000_rx_ring_configure(${e1000::RxRing.ref} self) | |
1241 + { | |
1242 + // XXX Reread & Fix everything down there (data structure changes and so on) | |
1243 + | |
1244 + // Receive initialization (section 14.4): | |
1245 + // | |
1246 + // 1. Program the receive address, in RAL/RAH; | |
1247 + // 2. Initialize the Multicast Table Array; | |
1248 + // 3. Program the interrupt mask register (done in | |
1249 + // e1000::activate_device_interruption); | |
1250 + // 4. Allocate the receive descriptor ring and map it to make it | |
1251 + // accessible by the device; | |
1252 + // 5. Write the start address of the ring in RDBAL/RDBAH and set | |
1253 + // RDLEN (Receive Descriptor Length) to the size of the ring; | |
1254 + // 6. Set the RDH/RDT (Receive Descriptor Head/Tail) indexes to the | |
1255 + // beginning and end of the ring; | |
1256 + // 7. Make sure that RCTL.BSIZE and .BSEX are at 0 to configure the | |
1257 + // receive buffer size to 2048 bytes (e1000::rx_buffer_len). | |
1258 + // 8. Set RCTL.EN to enable the receiver. | |
1259 + // | |
1260 + // The ugly casts here are caused by the lack of CNorm unstrict. | |
1261 + | |
1262 + int i; | |
1263 + | |
1264 + // 1. Program the receive address | |
1265 + | |
1266 + // (We should use uint{32,16}_t but CNorm doesn't know them yet) | |
1267 + rtx_e1000_reg_write32( | |
1268 + ${local.self.hw_ctx}, E1000_RAL, | |
1269 + *(unsigned int *)(${local.self.hw_ctx.net_dev.dev_addr}) | |
1270 + ); | |
1271 + // The 16 upper bits of RAH also store the AS bits (which should be | |
1272 + // 0) and the AV bit (should be 1 to set the address as valid). | |
1273 + rtx_e1000_reg_write32( | |
1274 + ${local.self.hw_ctx}, E1000_RAH, | |
1275 + *(unsigned short *)(&${local.self.hw_ctx.net_dev.dev_addr}[4]) | |
1276 + ); | |
1277 + rtx_e1000_reg_set32(${local.self.hw_ctx}, E1000_RAH, E1000_RAH_AV); | |
1278 + | |
1279 + ${Log::info("rx_ring_configure: receive address programmed")}; | |
1280 + | |
1281 + // 2. Initialize the MTA | |
1282 + | |
1283 + for (i = 0; i != 128; ++i) // TODO Remove that hardcoded 128 | |
1284 + rtx_e1000_reg_write32(${local.self.hw_ctx}, E1000_MTA + i * 4, 0); | |
1285 + | |
1286 + ${Log::info("rx_ring_configure: MTA init done")}; | |
1287 + | |
1288 + // 5. Save the emplacement and the size of the ring in RDBA/RDLEN | |
1289 + rtx_e1000_reg_write32( | |
1290 + ${local.self.hw_ctx}, E1000_RDBAL, | |
1291 + ${local.self.hw_ctx}->rx_ring.dma_base & 0xffffffff | |
1292 + ); | |
1293 + rtx_e1000_reg_write32( | |
1294 + ${local.self.hw_ctx}, E1000_RDBAH, | |
1295 + ${local.self.hw_ctx}->rx_ring.dma_base >> 32 | |
1296 + ); | |
1297 + rtx_e1000_reg_write32( | |
1298 + ${local.self.hw_ctx}, E1000_RDLEN, | |
1299 + ${local.self.hw_ctx}->rx_ring.size | |
1300 + ); | |
1301 + | |
1302 + // 6. Setup RDH/RDT | |
1303 + rtx_e1000_reg_write32(${local.self.hw_ctx}, E1000_RDH, 0); | |
1304 + rtx_e1000_reg_write32( | |
1305 + ${local.self.hw_ctx}, E1000_RDT, | |
1306 + ${config.rx_ring_size} - 1 | |
1307 + ); | |
1308 + | |
1309 + // 7. Configure the buffer size | |
1310 + rtx_e1000_reg_set32( | |
1311 + ${local.self.hw_ctx}, E1000_RCTL, | |
1312 + E1000_RCTL_BSIZE_${config.rx_buffer_len} | |
1313 + ); | |
1314 + | |
1315 + // 8. Enable the receiver | |
1316 + rtx_e1000_reg_set32(${local.self.hw_ctx}, E1000_RCTL, E1000_RCTL_EN); | |
1317 + | |
1318 + ${Log::info("rx_ring_configure: receive registers configured and receiver enabled")}; | |
1319 + | |
1320 + return 0; | |
1107 } | 1321 } |
1108 } | 1322 } |
1109 | 1323 |
1110 - chunk ::CALL() | 1324 - chunk ::CALL() |
1111 + chunk Ethernet::adapter_load_mac_address(Ethernet::Device rtx_ether_ctx) | 1325 + method init(e1000::Context hw_ctx, Builtin::number desc_count) |
1112 { | 1326 { |
1113 - rtx_e1000_register_write32(${ctx}, ${reg_offset}, ${value}); | 1327 - rtx_e1000_register_write32(${ctx}, ${reg_offset}, ${value}); |
1114 - } | 1328 + ${self.ring.init(hw_ctx, desc_count, self.desc_size)}; |
1115 - } | 1329 + } |
1116 + { | 1330 + |
1117 + ${e1000::Context.ref} hw_ctx = &${local.rtx_ether_ctx}->hw_ctx; | 1331 + method alloc() |
1118 + // Shamelessly borrowed from Minix | 1332 + { |
1119 + for (int i = 0; i < 3; ++i) { | 1333 + rtx_e1000_rx_ring_alloc_resources(${self}); |
1120 + rtx_e1000_reg_write32(hw_ctx, E1000_EEPROM_READ, (i << 8) | 1); | 1334 + } |
1121 + int value; | 1335 + |
1122 + do { | 1336 + method configure() |
1123 + value = rtx_e1000_reg_read32(hw_ctx, E1000_EEPROM_READ); | 1337 + { |
1124 + } while ((value & (1 << 4)) == 0); | 1338 + rtx_e1000_rx_ring_configure(${self}); |
1125 + value >>= 16; | 1339 + } |
1126 + // NOTE: I'm not sure if Ethernet::Device should be | 1340 + |
1127 + // accessed directly here. But since we need to take it in | 1341 + map |
1128 + // parameter (so we can get back our e1000::Context) it | 1342 + { |
1129 + // seems inadequate to set this in another way: | 1343 + // TODO: fix cast to directly get the attributes from the Ring: |
1130 + ${local.rtx_ether_ctx.dev_addr}[i * 2] = value & 0xff; | 1344 + hw_ctx: ((int)(${self})->hw_ctx); |
1131 + ${local.rtx_ether_ctx.dev_addr}[i * 2 + 1] = (value >> 8) & 0xff; | 1345 + dma: ((int)(${self})->dma); |
1132 + } | 1346 + size: ((int)(${self})->size); |
1347 + descs: ((int)(${self})->descs); | |
1348 + buffs: ((int)(${self})->buffs); | |
1349 + desc_size: sizeof(/* TODO: get the generated type... ${e1000::RxDescriptor} */int); | |
1350 } | |
1351 } | |
1133 | 1352 |
1134 - template sequence e1000::register_set32(e1000::Context ctx, e1000::Register reg_offset, ::number value) | 1353 - template sequence e1000::register_set32(e1000::Context ctx, e1000::Register reg_offset, ::number value) |
1135 - { | 1354 + template type e1000::TxRing() |
1355 { | |
1136 - chunk LKM::prototypes() | 1356 - chunk LKM::prototypes() |
1137 - { | 1357 + decl data_types() |
1358 { | |
1138 - /* FIXME: See issue #54 */ | 1359 - /* FIXME: See issue #54 */ |
1139 - static void rtx_e1000_register_set32(/*const*/ ${e1000::Context.ref}, unsigned int, unsigned int); | 1360 - static void rtx_e1000_register_set32(/*const*/ ${e1000::Context.ref}, unsigned int, unsigned int); |
1140 - } | 1361 + ${e1000::Ring} ring; |
1141 - | 1362 } |
1363 | |
1142 - chunk LKM::code() | 1364 - chunk LKM::code() |
1143 - { | 1365 + chunk LKM::prototypes() |
1366 { | |
1144 - /* FIXME: See issue #54 */ | 1367 - /* FIXME: See issue #54 */ |
1145 - static void rtx_e1000_register_set32(/*const*/ ${e1000::Context.ref} ctx, unsigned int reg_offset, unsigned int value) | 1368 - static void rtx_e1000_register_set32(/*const*/ ${e1000::Context.ref} ctx, unsigned int reg_offset, unsigned int value) |
1146 - { | 1369 + static int rtx_e1000_tx_ring_alloc_resources(${e1000::TxRing.ref}); |
1370 + static void rtx_e1000_tx_ring_configure(${e1000::TxRing.ref}); | |
1371 + } | |
1372 + | |
1373 + chunk LKM::code() | |
1374 + { | |
1375 + static int rtx_e1000_tx_ring_alloc_resources(${e1000::TxRing.ref} self) | |
1376 { | |
1147 - iowrite32(rtx_e1000_register_read32(ctx, reg_offset) | value, ctx->ioaddr + reg_offset); | 1377 - iowrite32(rtx_e1000_register_read32(ctx, reg_offset) | value, ctx->ioaddr + reg_offset); |
1148 + ${Log::info("mac address loaded from the EEPROM")}; | 1378 + return 0; |
1379 + } | |
1380 + | |
1381 + static void rtx_e1000_tx_ring_configure(${e1000::TxRing.ref} self) | |
1382 + { | |
1383 + // return ; XXX wtf fails with: | |
1384 + // function 'rtxPH_compile(local_node : node, compile : node, node_idx : value)' hasn't been implemented | |
1149 } | 1385 } |
1150 } | 1386 } |
1151 | 1387 |
1152 - chunk ::CALL() | 1388 - chunk ::CALL() |
1153 + // For e1000, this part is documented in the Intel Gigabit Ethernet | 1389 + method init(e1000::Context hw_ctx, Builtin::number desc_count) |
1154 + // Controller Software Developper manual. (You can find it in the | |
1155 + // doc/hardware directory). | |
1156 + chunk Ethernet::adapter_setup_rx_tx(Ethernet::Device rtx_ether_ctx) | |
1157 { | 1390 { |
1158 - rtx_e1000_register_set32(${ctx}, ${reg_offset}, ${value}); | 1391 - rtx_e1000_register_set32(${ctx}, ${reg_offset}, ${value}); |
1159 - } | 1392 - } |
1160 - } | 1393 - } |
1161 + { | 1394 - |
1162 + ${e1000::Context.ref} hw_ctx = &${local.rtx_ether_ctx}->hw_ctx; | |
1163 | |
1164 - template sequence e1000::register_unset32(e1000::Context ctx, e1000::Register reg_offset, ::number value) | 1395 - template sequence e1000::register_unset32(e1000::Context ctx, e1000::Register reg_offset, ::number value) |
1165 - { | 1396 - { |
1166 - chunk LKM::prototypes() | 1397 - chunk LKM::prototypes() |
1167 - { | 1398 - { |
1168 - /* FIXME: See issue #54 */ | 1399 - /* FIXME: See issue #54 */ |
1169 - static void rtx_e1000_register_unset32(/*const*/ ${e1000::Context.ref}, unsigned int, unsigned int); | 1400 - static void rtx_e1000_register_unset32(/*const*/ ${e1000::Context.ref}, unsigned int, unsigned int); |
1170 - } | 1401 + ${self.ring.init(hw_ctx, desc_count, self.desc_size)}; |
1171 + // "General Configuration" (section 14.3): | 1402 } |
1172 + // | |
1173 + // - CTRL.ASDE/CTRL.SLU: Let the PHY handle the speed detection & | |
1174 + // negociation; | |
1175 + // - CTRL.LRST/FRCSPD: Unset them to initiate the auto-negociation; | |
1176 + // - CTRL.PHY_RST: Unset it; | |
1177 + // - CTRL.ILOS: Unset it (ILOS is Invert Loss Of Signal); | |
1178 + // - CTRL.VME: Make sure it's not set to disable VLAN support; | |
1179 + // - Set the control flow registers to 0; | |
1180 + // - Finally, initialize all the statistic registers from | |
1181 + // E1000_CRCERRS to E1000_TSCTFC. | |
1182 + // | |
1183 + // XXX #46: Use the read/write/set/unset methods on Context | |
1184 + rtx_e1000_reg_set32(hw_ctx, E1000_CTRL, E1000_CMD_ASDE|E1000_CMD_SLU); | |
1185 + rtx_e1000_reg_unset32( | |
1186 + hw_ctx, | |
1187 + E1000_CTRL, | |
1188 + E1000_CMD_LRST|E1000_CMD_FRCSPD|E1000_CMD_PHY_RST| | |
1189 + E1000_CMD_ILOS|E1000_CMD_VME | |
1190 + ); | |
1191 + rtx_e1000_reg_write32(hw_ctx, E1000_FCAH, 0); | |
1192 + rtx_e1000_reg_write32(hw_ctx, E1000_FCAL, 0); | |
1193 + rtx_e1000_reg_write32(hw_ctx, E1000_FCT, 0); | |
1194 + rtx_e1000_reg_write32(hw_ctx, E1000_FCTTV, 0); | |
1195 + for (int i = 0; i != 64; ++i) | |
1196 + rtx_e1000_reg_write32(hw_ctx, E1000_CRCERRS + i * 4, 0); | |
1197 | 1403 |
1198 - chunk LKM::code() | 1404 - chunk LKM::code() |
1199 - { | 1405 + method alloc() |
1406 { | |
1200 - /* FIXME: See issue #54 */ | 1407 - /* FIXME: See issue #54 */ |
1201 - static void rtx_e1000_register_unset32(/*const*/ ${e1000::Context.ref} ctx, unsigned int reg_offset, unsigned int value) | 1408 - static void rtx_e1000_register_unset32(/*const*/ ${e1000::Context.ref} ctx, unsigned int reg_offset, unsigned int value) |
1202 - { | 1409 - { |
1203 - iowrite32(rtx_e1000_register_read32(ctx, reg_offset) & ~value, ctx->ioaddr + reg_offset); | 1410 - iowrite32(rtx_e1000_register_read32(ctx, reg_offset) & ~value, ctx->ioaddr + reg_offset); |
1204 + ${Log::info("adapter_setup: general configuration done")}; | 1411 - } |
1205 } | 1412 + rtx_e1000_tx_ring_alloc_resources(${self}); |
1206 } | 1413 } |
1207 | 1414 |
1208 - chunk ::CALL() | 1415 - chunk ::CALL() |
1209 + chunk Ethernet::adapter_enable_interrupts(Ethernet::Device) | 1416 + method configure() |
1210 { | 1417 { |
1211 - rtx_e1000_register_unset32(${ctx}, ${reg_offset}, ${value}); | 1418 - rtx_e1000_register_unset32(${ctx}, ${reg_offset}, ${value}); |
1212 - } | 1419 + rtx_e1000_tx_ring_configure(${self}); |
1213 - } | 1420 } |
1214 + { | 1421 - } |
1215 + ${e1000::Context.ref} hw_ctx = &${local.rtx_ether_ctx}->hw_ctx; | |
1216 + rtx_e1000_reg_write32( | |
1217 + hw_ctx, | |
1218 + E1000_IMS, | |
1219 + E1000_INTR_TXDW|E1000_INTR_TXQE|E1000_INTR_LSC| | |
1220 + E1000_INTR_RXO|E1000_INTR_RXT0 | |
1221 + ); | |
1222 | 1422 |
1223 - template sequence activate_device_interruption(Ethernet::Device rtx_ether_ctx) | 1423 - template sequence activate_device_interruption(Ethernet::Device rtx_ether_ctx) |
1224 - { | 1424 - { |
1225 - chunk ::CALL() | 1425 - chunk ::CALL() |
1226 - { | 1426 + map |
1427 { | |
1227 - rtx_e1000_register_write32(&${rtx_ether_ctx}->hw_ctx, E1000_IMS, | 1428 - rtx_e1000_register_write32(&${rtx_ether_ctx}->hw_ctx, E1000_IMS, |
1228 - E1000_INTR_TXDW | | 1429 - E1000_INTR_TXDW | |
1229 - E1000_INTR_TXQE | | 1430 - E1000_INTR_TXQE | |
1230 - E1000_INTR_LSC | | 1431 - E1000_INTR_LSC | |
1231 - E1000_INTR_RXO | | 1432 - E1000_INTR_RXO | |
1314 - { | 1515 - { |
1315 - ${Log::info("handle_interrupt: RxRing: overrun")}; | 1516 - ${Log::info("handle_interrupt: RxRing: overrun")}; |
1316 - } | 1517 - } |
1317 - | 1518 - |
1318 - return IRQ_HANDLED; | 1519 - return IRQ_HANDLED; |
1319 + // XXX We should probably move that elsewhere (it just used to | 1520 - } |
1320 + // be done right after we enabled interrupts when this was | 1521 - } |
1321 + // still in lkm.rtx): | 1522 - } |
1322 + // XXX #46: ${local.hw_ctx.print_status()}; | 1523 - |
1323 + rtx_e1000_print_status(hw_ctx); | |
1324 } | |
1325 } | |
1326 - } | |
1327 | |
1328 - template sequence e1000::xmit(Ethernet::Device rtx_ether_ctx, Socket::AbstractSKBuff kernel_skb) | 1524 - template sequence e1000::xmit(Ethernet::Device rtx_ether_ctx, Socket::AbstractSKBuff kernel_skb) |
1329 - { | 1525 - { |
1330 - chunk ::CALL() | 1526 - chunk ::CALL() |
1331 + chunk Ethernet::disable_interrupts(Ethernet::Device rtx_ether_ctx) | 1527 - { |
1332 { | |
1333 - /* | 1528 - /* |
1334 - * Put packets on the TX ring, must return NETDEV_TX_OK or | 1529 - * Put packets on the TX ring, must return NETDEV_TX_OK or |
1335 - * NETDEV_TX_BUSY. | 1530 - * NETDEV_TX_BUSY. |
1336 - */ | 1531 - */ |
1337 + { ${Log::info("adapter_disable_interrupts: TBD...")}; } | 1532 - |
1338 + } | |
1339 | |
1340 - ${Socket::SKBuff} skb; | 1533 - ${Socket::SKBuff} skb; |
1341 - ${e1000::Context.ref} hw_ctx; | 1534 - ${e1000::Context.ref} hw_ctx; |
1342 - ${e1000::TxRing.ref} tx_ring; | 1535 - ${e1000::TxRing.ref} tx_ring; |
1343 - ${Device::AbstractDevice.ref} devp; | 1536 - ${Device::AbstractDevice.ref} devp; |
1344 + chunk Ethernet::adapter_handle_interrupt(Ethernet::Device rtx_ether_ctx) | 1537 - |
1345 + { | |
1346 + { | |
1347 + ${e1000::Context.ref} hw_ctx = &${local.rtx_ether_ctx}->hw_ctx; | |
1348 + unsigned int icr = rtx_e1000_reg_read32(hw_ctx, E1000_ICR); | |
1349 + pr_info("%s: interrupt received, ICR: 0x%x", ${config.name}, icr); | |
1350 + if (icr) { | |
1351 + if (icr & E1000_INTR_LSC) { | |
1352 + ${Log::info("handle_interrupt: cable link status changed, dumping card status:")}; | |
1353 + // XXX #46: ${local.hw_ctx.print_status()}; | |
1354 + rtx_e1000_print_status(hw_ctx); | |
1355 + } | |
1356 + if (icr & (E1000_INTR_TXQE|E1000_INTR_TXDW)) { | |
1357 + ${Log::info("handle_interrupt: TxRing: packet(s) sent")}; | |
1358 + } | |
1359 + if (icr & E1000_INTR_RXT0) { | |
1360 + ${Log::info("handle_interrupt: RxRing: packet(s) received")}; | |
1361 + } | |
1362 + if (icr & E1000_INTR_RXO) { | |
1363 + ${Log::info("handle_interrupt: RxRing: overrun")}; | |
1364 + } | |
1365 | |
1366 - ${local.skb.init(kernel_skb)}; | 1538 - ${local.skb.init(kernel_skb)}; |
1367 - hw_ctx = &${rtx_ether_ctx}->hw_ctx; | 1539 - hw_ctx = &${rtx_ether_ctx}->hw_ctx; |
1368 - tx_ring = &hw_ctx->tx_ring; | 1540 - tx_ring = &hw_ctx->tx_ring; |
1369 - devp = (${Device::AbstractDevice.ref})${rtx_ether_ctx.device}; | 1541 - devp = (${Device::AbstractDevice.ref})${rtx_ether_ctx.device}; |
1370 + // XXX: This sucks since we don't know the pointcut context: | 1542 - |
1371 + return IRQ_HANDLED; | |
1372 + } | |
1373 + } | |
1374 + } | |
1375 | |
1376 - ${Log::info("xmit: skbuff details:")}; | 1543 - ${Log::info("xmit: skbuff details:")}; |
1377 - /* | 1544 - /* |
1378 - * skb does not expand on the bound C variable (should be | 1545 - * skb does not expand on the bound C variable (should be |
1379 - * rtx_skbuff), which is funny because it works for the | 1546 - * rtx_skbuff), which is funny because it works for the |
1380 - * sequence template call right after. | 1547 - * sequence template call right after. |
1382 - /* | 1549 - /* |
1383 - * XXX: doesn't work (I tried to pass self explicitely too): | 1550 - * XXX: doesn't work (I tried to pass self explicitely too): |
1384 - * ${local.skb.dump_infos()}; | 1551 - * ${local.skb.dump_infos()}; |
1385 - */ | 1552 - */ |
1386 - rtx_socket_skbuff_dump_infos(&skb); | 1553 - rtx_socket_skbuff_dump_infos(&skb); |
1387 + chunk Ethernet::adapter_xmit(Ethernet::Device rtx_ether_ctx, Socket::SKBuff rtx_skb) | 1554 - |
1388 + { | |
1389 + { ${Log::info("adapter_xmit: TBD...")}; } | |
1390 + } | |
1391 | |
1392 - /* | 1555 - /* |
1393 - * The transmission is going to be several steps: | 1556 - * The transmission is going to be several steps: |
1394 - * 1. TCP Segmentation Offload & Checksum Offloading: pick a | 1557 - * 1. TCP Segmentation Offload & Checksum Offloading: pick a |
1395 - * descriptor from the tx ring and fill it as a context | 1558 - * descriptor from the tx ring and fill it as a context |
1396 - * descriptor to allow the card to slice into several packets | 1559 - * descriptor to allow the card to slice into several packets |
1397 - * according to the MSS; | 1560 - * according to the MSS; |
1398 - * 2. DMA Map the skbuff data as slices of 4096; | 1561 - * 2. DMA Map the skbuff data as slices of 4096; |
1399 - * 3. Signal the hardware that data is available via a tx desc. | 1562 - * 3. Signal the hardware that data is available via a tx desc. |
1400 - */ | 1563 - */ |
1401 + chunk Ethernet::adapter_disable_rx(Ethernet::Device rtx_ether_ctx) | 1564 - |
1402 + { | |
1403 + { ${Log::info("adapter_disable_rx: TBD..")}; } | |
1404 + } | |
1405 | |
1406 - /* XXX: same thing wanted to use: ${local.tx_ring.descriptors_remaining()} */ | 1565 - /* XXX: same thing wanted to use: ${local.tx_ring.descriptors_remaining()} */ |
1407 - if (!rtx_e1000_tx_ring_descriptors_remaining(tx_ring)) | 1566 - if (!rtx_e1000_tx_ring_descriptors_remaining(tx_ring)) |
1408 - return NETDEV_TX_BUSY; | 1567 - return NETDEV_TX_BUSY; |
1409 + chunk Ethernet::adpater_disable_tx(Ethernet::Device rtx_ether_ctx) | 1568 - |
1410 + { | |
1411 + { ${Log::info("adapter_disable_tx: TBD..")}; } | |
1412 + } | |
1413 | |
1414 - /* 1. Offloading */ | 1569 - /* 1. Offloading */ |
1415 + chunk Ethernet::adapter_free_rx_tx(Ethernet::Device rtx_ether_ctx) | 1570 - |
1416 + { | |
1417 + { ${Log::info("adapter_free_rx_tx: TBD..")}; } | |
1418 + } | |
1419 | |
1420 - /* XXX: ${local.tx_ring.tso_cksum_offload(skb)}; */ | 1571 - /* XXX: ${local.tx_ring.tso_cksum_offload(skb)}; */ |
1421 - if (rtx_e1000_tx_ring_tso_cksum_offload(tx_ring, &skb)) | 1572 - if (rtx_e1000_tx_ring_tso_cksum_offload(tx_ring, &skb)) |
1422 - { | 1573 - { |
1423 - ${Log::info("xmit: the packet needs to be fragmented and/or checksummed but this not implemented yet!")}; | 1574 - ${Log::info("xmit: the packet needs to be fragmented and/or checksummed but this not implemented yet!")}; |
1424 - goto err_offload; | 1575 - goto err_offload; |
1425 - } | 1576 - } |
1426 | 1577 - |
1427 - /* 2. Map the data */ | 1578 - /* 2. Map the data */ |
1428 + method print_status() | 1579 - |
1429 + { | |
1430 + rtx_e1000_print_status(${self}); | |
1431 + } | |
1432 | |
1433 - /* XXX: ${local.skb.map_to(devp.k_device)}; */ | 1580 - /* XXX: ${local.skb.map_to(devp.k_device)}; */ |
1434 - if (rtx_socket_skbuff_map(&skb, ${devp.k_device}, DMA_TO_DEVICE)) | 1581 - if (rtx_socket_skbuff_map(&skb, ${devp.k_device}, DMA_TO_DEVICE)) |
1435 - { | 1582 - { |
1436 - ${Log::info("xmit: can't DMA map a SKbuff")}; | 1583 - ${Log::info("xmit: can't DMA map a SKbuff")}; |
1437 - goto err_skb_map_to; | 1584 - goto err_skb_map_to; |
1450 - err_offload: | 1597 - err_offload: |
1451 - err_skb_map_to: | 1598 - err_skb_map_to: |
1452 - /* XXX: ${local.skb.unmap_to_and_free(local.dev)}; */ | 1599 - /* XXX: ${local.skb.unmap_to_and_free(local.dev)}; */ |
1453 - rtx_socket_skbuff_unmap_and_free(&skb, ${devp.k_device}, DMA_TO_DEVICE); | 1600 - rtx_socket_skbuff_unmap_and_free(&skb, ${devp.k_device}, DMA_TO_DEVICE); |
1454 - return NETDEV_TX_OK; | 1601 - return NETDEV_TX_OK; |
1455 + map | 1602 + // TODO: fix cast to directly get the attributes from the Ring: |
1456 + { | 1603 + hw_ctx: ((int)(${self})->hw_ctx); |
1457 + io: ${self}->io; | 1604 + dma: ((int)(${self})->dma); |
1458 + rx_ring: ${self}->rx_ring; | 1605 + size: ((int)(${self})->size); |
1459 + tx_ring: ${self}->tx_ring; | 1606 + descs: ((int)(${self})->descs); |
1607 + buffs: ((int)(${self})->buffs); | |
1608 + desc_size: sizeof(/* TODO: get the generated type ${e1000::TxDescriptor} */int); | |
1460 } | 1609 } |
1461 } | 1610 } |
1462 } | 1611 } |
1463 diff --git a/rathaxes/samples/e1000/e1000.rti b/rathaxes/samples/e1000/e1000.rti | 1612 diff --git a/rathaxes/samples/e1000/e1000.rti b/rathaxes/samples/e1000/e1000.rti |
1464 old mode 100755 | |
1465 new mode 100644 | |
1466 --- a/rathaxes/samples/e1000/e1000.rti | 1613 --- a/rathaxes/samples/e1000/e1000.rti |
1467 +++ b/rathaxes/samples/e1000/e1000.rti | 1614 +++ b/rathaxes/samples/e1000/e1000.rti |
1468 @@ -1,157 +1,115 @@ | 1615 @@ -1,157 +1,122 @@ |
1469 interface e1000 : Socket, Ethernet, DMA, PCI, LKM, Builtin | 1616 -interface e1000 : Socket, Ethernet, DMA, PCI, LKM, Builtin |
1617 +interface e1000 : Socket, Ethernet, Device, DMA, PCI, LKM, Builtin | |
1470 { | 1618 { |
1471 - required variable Builtin::number rx_ring_size; | 1619 - required variable Builtin::number rx_ring_size; |
1472 - required variable Builtin::number tx_ring_size; | 1620 - required variable Builtin::number tx_ring_size; |
1473 - required variable Builtin::number rx_buffer_len; | 1621 - required variable Builtin::number rx_buffer_len; |
1474 - required variable Builtin::number tx_max_data_per_desc; | 1622 - required variable Builtin::number tx_max_data_per_desc; |
1496 + attribute Socket::SKBuff.ref sk_buff; | 1644 + attribute Socket::SKBuff.ref sk_buff; |
1497 + attribute DMA::DMAHandle.ref dma; | 1645 + attribute DMA::DMAHandle.ref dma; |
1498 } | 1646 } |
1499 | 1647 |
1500 - provided type TxDescriptor | 1648 - provided type TxDescriptor |
1501 + // I wish we could just leave those methods in the Context type but we also | 1649 + provided type Context |
1502 + // need them from the rings and that would mean a circular dependency | |
1503 + // between the context and the rings and Rathaxes can't handle it. | |
1504 + provided type MMIO | |
1505 { | 1650 { |
1506 decl data_types(); | 1651 decl data_types(); |
1507 - method init(); | 1652 - method init(); |
1508 + | 1653 + |
1654 + chunk LKM::includes(); | |
1509 + chunk LKM::prototypes(); | 1655 + chunk LKM::prototypes(); |
1510 + chunk LKM::code(); | 1656 + chunk LKM::code(); |
1657 + chunk Ethernet::HardwareContext(); | |
1658 + | |
1659 + // NOTE: Those callbacks/hooks should probably be in the front-end: | |
1660 + | |
1661 + chunk Ethernet::adapter_init_context(Ethernet::Device, Builtin::symbol); | |
1662 + chunk Ethernet::adapter_reset(Ethernet::Device); | |
1663 + chunk Ethernet::adapter_load_mac_address(Ethernet::Device); | |
1664 + chunk Ethernet::adapter_setup_rx_tx(Ethernet::Device); | |
1665 + chunk Ethernet::adapter_enable_interrupts(Ethernet::Device); | |
1666 + chunk Ethernet::adapter_disable_interrupts(Ethernet::Device); | |
1667 + chunk Ethernet::adapter_handle_interrupt(Ethernet::Device); | |
1668 + chunk Ethernet::adapter_xmit(Ethernet::Device, Socket::SKBuff); | |
1669 + chunk Ethernet::adapter_disable_rx(Ethernet::Device); | |
1670 + chunk Ethernet::adapter_disable_tx(Ethernet::Device); | |
1671 + chunk Ethernet::adapter_free_rx_tx(Ethernet::Device); | |
1511 + | 1672 + |
1512 + method init(Builtin::symbol); | 1673 + method init(Builtin::symbol); |
1513 + method read32(Register); | 1674 + method print_status(); |
1514 + method write32(Register, Builtin::number); | 1675 + method reg_read32(Register); |
1515 + method set32(Register, Builtin::number); | 1676 + method reg_write32(Register, Builtin::number); |
1516 + method unset32(Register, Builtin::number); | 1677 + method reg_set32(Register, Builtin::number); |
1517 + | 1678 + method reg_unset32(Register, Builtin::number); |
1518 + attribute Builtin::symbol.scalar io; | 1679 + |
1680 + // XXX: Circular dependency with the rings, this will prevent us to | |
1681 + // call methods even when issue $46 is resolved, and it also forces | |
1682 + // us to hardcode generated types in the definition of the type: | |
1683 + attribute Builtin::symbol.scalar rx_ring; | |
1684 + attribute Builtin::symbol.scalar tx_ring; | |
1685 + | |
1686 + attribute Ethernet::Device.ref net_dev; | |
1519 + } | 1687 + } |
1520 + | 1688 + |
1521 + provided type Ring | 1689 + provided type Ring |
1522 + { | 1690 + { |
1523 + decl data_types(); | 1691 + decl data_types(); |
1524 + | 1692 + |
1525 + chunk LKM::prototypes(); | 1693 + chunk LKM::prototypes(); |
1526 + chunk LKM::code(); | 1694 + chunk LKM::code(); |
1527 + | 1695 + |
1528 + method init(MMIO, Builtin::number, Builtin::number); | 1696 + method init(e1000::Context, Builtin::number); |
1529 + | 1697 + |
1530 + attribute MMIO.scalar io; | 1698 + // Keep a backref to The context since it's going to be needed for of |
1531 + attribute DMA::DMAHandle.scalar dma; | 1699 + // operations involving the ethernet device, flags on the context, etc. |
1700 + attribute Context.ref hw_ctx; | |
1701 + | |
1702 + attribute DMA::DMAHandle.scalar dma; | |
1532 + attribute Builtin::number.scalar size; // Total size in bytes | 1703 + attribute Builtin::number.scalar size; // Total size in bytes |
1533 + attribute Builtin::symbol.ref descs; | 1704 + attribute Builtin::symbol.ref descs; |
1534 + attribute Buffer.ref buffs; | 1705 + attribute Buffer.ref buffs; |
1535 } | 1706 } |
1536 | 1707 |
1543 - chunk Ethernet::adapter_init_rx(Ethernet::Device); | 1714 - chunk Ethernet::adapter_init_rx(Ethernet::Device); |
1544 + chunk LKM::prototypes(); | 1715 + chunk LKM::prototypes(); |
1545 + chunk LKM::code(); | 1716 + chunk LKM::code(); |
1546 | 1717 |
1547 - attribute DMA::DMAHandle.scalar dma_base; | 1718 - attribute DMA::DMAHandle.scalar dma_base; |
1548 - attribute Builtin::number.scalar size; | 1719 + method init(e1000::Context, Builtin::number); |
1549 + method init(MMIO, Builtin::number); | |
1550 + method alloc(); // Returns != 0 on failure | 1720 + method alloc(); // Returns != 0 on failure |
1551 + | 1721 + method free(); |
1552 + attribute RxDescriptor.scalar descs; | 1722 + method configure(); |
1553 + } | 1723 + |
1554 + | 1724 + // Re-expose all the Ring attributes + the size of a single descriptor: |
1555 + provided type TxRing | 1725 + attribute Context.ref hw_ctx; |
1556 + { | 1726 + attribute DMA::DMAHandle.scalar dma; |
1557 + decl data_types(); | 1727 attribute Builtin::number.scalar size; |
1558 + | 1728 - } |
1559 + chunk LKM::prototypes(); | 1729 - |
1560 + chunk LKM::code(); | 1730 - provided type Context |
1561 + | 1731 - { |
1562 + method init(MMIO, Builtin::number); | |
1563 + method alloc(); // Returns != 0 on failure | |
1564 + | |
1565 + attribute TxDescriptor.scalar descs; | |
1566 } | |
1567 | |
1568 provided type Context | |
1569 { | |
1570 - chunk Ethernet::HardwareContext(); | 1732 - chunk Ethernet::HardwareContext(); |
1571 decl data_types(); | 1733 - decl data_types(); |
1572 | 1734 - |
1573 - /* XXX: | 1735 - /* XXX: |
1574 - * These callbacks/Hooks which should probably be in the front-end. | 1736 - * These callbacks/Hooks which should probably be in the front-end. |
1575 - * Also, I'm not too happy about the names, it's difficult to make | 1737 - * Also, I'm not too happy about the names, it's difficult to make |
1576 - * the difference between the probe and open parts. | 1738 - * the difference between the probe and open parts. |
1577 - */ | 1739 - */ |
1578 - chunk Ethernet::adapter_init_context(Ethernet::Device, | 1740 - chunk Ethernet::adapter_init_context(Ethernet::Device, |
1579 - Builtin::number, | 1741 - Builtin::number, |
1580 - Builtin::symbol); | 1742 - Builtin::symbol); |
1581 + chunk LKM::includes(); | 1743 - chunk Ethernet::adapter_reset(Ethernet::Device); |
1582 + chunk LKM::prototypes(); | 1744 - chunk Ethernet::adapter_load_mac_address(Ethernet::Device); |
1583 + chunk LKM::code(); | |
1584 + chunk Ethernet::HardwareContext(); | |
1585 + | |
1586 + // NOTE: Those callbacks/hooks should probably be in the front-end: | |
1587 + | |
1588 + chunk Ethernet::adapter_init_context(Ethernet::Device, Builtin::symbol); | |
1589 chunk Ethernet::adapter_reset(Ethernet::Device); | |
1590 chunk Ethernet::adapter_load_mac_address(Ethernet::Device); | |
1591 - chunk Ethernet::adapter_setup(Ethernet::Device); | 1745 - chunk Ethernet::adapter_setup(Ethernet::Device); |
1592 + chunk Ethernet::adapter_setup_rx_tx(Ethernet::Device); | 1746 - |
1593 + chunk Ethernet::adapter_enable_interrupts(Ethernet::Device); | 1747 - attribute RxRing.scalar rx_ring; |
1594 + chunk Ethernet::adapter_disable_interrupts(Ethernet::Device); | |
1595 + chunk Ethernet::adapter_handle_interrupt(Ethernet::Device); | |
1596 + chunk Ethernet::adapter_xmit(Ethernet::Device, Socket::SKBuff); | |
1597 + chunk Ethernet::adapter_disable_rx(Ethernet::Device); | |
1598 + chunk Ethernet::adapter_disable_tx(Ethernet::Device); | |
1599 + chunk Ethernet::adapter_free_rx_tx(Ethernet::Device); | |
1600 | |
1601 + method print_status(); | |
1602 + | |
1603 + attribute MMIO.scalar io; | |
1604 attribute RxRing.scalar rx_ring; | |
1605 - /* XXX: circular dependency with Contex: */ | 1748 - /* XXX: circular dependency with Contex: */ |
1606 - //attribute TxRing.scalar tx_ring; | 1749 - //attribute TxRing.scalar tx_ring; |
1607 - } | 1750 + attribute RxDescriptor.scalar descs; |
1608 - | 1751 + attribute Builtin::number.scalar desc_size; |
1609 - provided type TxRing | 1752 } |
1610 - { | 1753 |
1611 - chunk LKM::prototypes(); | 1754 provided type TxRing |
1612 - chunk LKM::code(); | 1755 { |
1756 + decl data_types(); | |
1757 + | |
1758 chunk LKM::prototypes(); | |
1759 chunk LKM::code(); | |
1613 - decl data_types(); | 1760 - decl data_types(); |
1614 - method init(); | 1761 - method init(); |
1615 - | 1762 |
1616 - /* XXX: Callback that should be in the front-end: */ | 1763 - /* XXX: Callback that should be in the front-end: */ |
1617 - chunk Ethernet::adapter_init_tx(Ethernet::Device); | 1764 - chunk Ethernet::adapter_init_tx(Ethernet::Device); |
1618 - | 1765 + method init(e1000::Context, Builtin::number); |
1766 + method alloc(); // Returns != 0 on failure | |
1767 + method free(); | |
1768 + method configure(); | |
1769 | |
1619 - /* Clean the ring (i.e: move the head closer to the tail): */ | 1770 - /* Clean the ring (i.e: move the head closer to the tail): */ |
1620 - method clean(); | 1771 - method clean(); |
1621 - /* Return the number of clean descriptors left in the ring: */ | 1772 - /* Return the number of clean descriptors left in the ring: */ |
1622 - method descriptors_remaining(); | 1773 - method descriptors_remaining(); |
1623 - method tso_cksum_offload(Socket::SKBuff); | 1774 - method tso_cksum_offload(Socket::SKBuff); |
1705 - provided sequence register_unset32(e1000::Context, e1000::Register, ::number) | 1856 - provided sequence register_unset32(e1000::Context, e1000::Register, ::number) |
1706 - { | 1857 - { |
1707 - provided chunk LKM::prototypes(); | 1858 - provided chunk LKM::prototypes(); |
1708 - provided chunk LKM::code(); | 1859 - provided chunk LKM::code(); |
1709 - provided chunk ::CALL(); | 1860 - provided chunk ::CALL(); |
1710 + attribute TxRing.scalar tx_ring; | 1861 + // Re-expose all the Ring attributes + the size of a single descriptor: |
1862 + attribute Context.ref hw_ctx; | |
1863 + attribute DMA::DMAHandle.scalar dma; | |
1864 + attribute Builtin::number.scalar size; | |
1865 + attribute TxDescriptor.scalar descs; | |
1866 + attribute Builtin::number.scalar desc_size; | |
1711 } | 1867 } |
1712 } | 1868 } |
1713 diff --git a/rathaxes/samples/e1000/ethernet.blt b/rathaxes/samples/e1000/ethernet.blt | 1869 diff --git a/rathaxes/samples/e1000/ethernet.blt b/rathaxes/samples/e1000/ethernet.blt |
1714 old mode 100755 | |
1715 new mode 100644 | |
1716 --- a/rathaxes/samples/e1000/ethernet.blt | 1870 --- a/rathaxes/samples/e1000/ethernet.blt |
1717 +++ b/rathaxes/samples/e1000/ethernet.blt | 1871 +++ b/rathaxes/samples/e1000/ethernet.blt |
1718 @@ -1,4 +1,4 @@ | 1872 @@ -1,4 +1,4 @@ |
1719 -with Ethernet, PCI, LKM, Log, Builtin | 1873 -with Ethernet, PCI, LKM, Log, Builtin |
1720 +with Ethernet, Socket, PCI, LKM, Log, Builtin | 1874 +with Ethernet, Socket, PCI, LKM, Log, Builtin |
1721 { | 1875 { |
1722 template type Ethernet::ProtocolId() | 1876 template type Ethernet::ProtocolId() |
1723 { | 1877 { |
1878 @@ -9,7 +9,7 @@ | |
1879 | |
1880 chunk LKM::prototypes() | |
1881 { | |
1882 - static const char *rtx_ethernet_protocol_id_to_str(unsigned short); | |
1883 + static const char *rtx_ethernet_protocol_id_to_str(unsigned short); | |
1884 } | |
1885 | |
1886 chunk LKM::data() | |
1887 @@ -28,7 +28,7 @@ | |
1888 | |
1889 chunk LKM::code() | |
1890 { | |
1891 - static const char *rtx_ethernet_protocol_id_to_str(unsigned short proto_id) | |
1892 + static const char *rtx_ethernet_protocol_id_to_str(unsigned short proto_id) | |
1893 { | |
1894 for (int i = 0; | |
1895 i != sizeof(rtx_ethernet_proto_table) / sizeof(rtx_ethernet_proto_table[0]); | |
1724 @@ -61,7 +61,7 @@ | 1896 @@ -61,7 +61,7 @@ |
1725 | 1897 |
1726 method init(Builtin::symbol dev) | 1898 method init(Builtin::symbol dev) |
1727 { | 1899 { |
1728 - ${self} = (${Ethernet::AbstractDevice} *)${dev}; | 1900 - ${self} = (${Ethernet::AbstractDevice} *)${dev}; |
1753 - template sequence Ethernet::open(Ethernet::Device dev) | 1925 - template sequence Ethernet::open(Ethernet::Device dev) |
1754 + template sequence Ethernet::open() | 1926 + template sequence Ethernet::open() |
1755 { | 1927 { |
1756 chunk LKM::includes() | 1928 chunk LKM::includes() |
1757 { | 1929 { |
1758 @@ -164,60 +167,68 @@ | 1930 @@ -157,100 +160,114 @@ |
1759 { | 1931 |
1760 static int rtx_ethernet_open(struct net_device *dev) | 1932 chunk LKM::prototypes() |
1933 { | |
1934 - static int rtx_ethernet_open(struct net_device *); | |
1935 + static int rtx_ethernet_open(struct net_device *); | |
1936 } | |
1937 | |
1938 chunk LKM::code() | |
1939 { | |
1940 - static int rtx_ethernet_open(struct net_device *dev) | |
1941 + static int rtx_ethernet_open(struct net_device *dev) | |
1761 { | 1942 { |
1762 - /* | 1943 - /* |
1763 - * XXX The casts are here because the compiler doesn't resolve | 1944 - * XXX The casts are here because the compiler doesn't resolve |
1764 - * "enclosed" type (e.g: local.var.enclosed) correctly. | 1945 - * "enclosed" type (e.g: local.var.enclosed) correctly. |
1765 - */ | 1946 - */ |
1815 + template sequence Ethernet::send() | 1996 + template sequence Ethernet::send() |
1816 { | 1997 { |
1817 chunk LKM::prototypes() | 1998 chunk LKM::prototypes() |
1818 { | 1999 { |
1819 - static int rtx_ethernet_xmit(struct sk_buff* skb, struct net_device *dev); | 2000 - static int rtx_ethernet_xmit(struct sk_buff* skb, struct net_device *dev); |
1820 + static int rtx_ethernet_xmit(struct sk_buff *skb, struct net_device *dev); | 2001 + static int rtx_ethernet_xmit(struct sk_buff *skb, struct net_device *dev); |
1821 } | 2002 } |
1822 | 2003 |
1823 chunk LKM::code() | 2004 chunk LKM::code() |
1824 { | 2005 { |
1825 - static int rtx_ethernet_xmit(struct sk_buff* kernel_skb, struct net_device *net_dev) | 2006 - static int rtx_ethernet_xmit(struct sk_buff* kernel_skb, struct net_device *net_dev) |
1826 + static int rtx_ethernet_xmit(struct sk_buff *k_skb, struct net_device *net_dev) | 2007 + static int rtx_ethernet_xmit(struct sk_buff *k_skb, struct net_device *net_dev) |
1827 { | 2008 { |
1828 ${Ethernet::Device.ref} rtx_ether_ctx = netdev_priv(net_dev); | 2009 ${Ethernet::Device.ref} rtx_ether_ctx = netdev_priv(net_dev); |
1829 - ${Socket::AbstractSKBuff.ref} rtx_skb = (${Socket::AbstractSKBuff.ref}) kernel_skb; | 2010 - ${Socket::AbstractSKBuff.ref} rtx_skb = (${Socket::AbstractSKBuff.ref}) kernel_skb; |
1830 + ${Socket::SKBuff.ref} rtx_skb; | 2011 + ${Socket::SKBuff.ref} rtx_skb; |
1831 | 2012 |
1847 - template sequence Ethernet::close(Ethernet::Device dev) | 2028 - template sequence Ethernet::close(Ethernet::Device dev) |
1848 + template sequence Ethernet::close() | 2029 + template sequence Ethernet::close() |
1849 { | 2030 { |
1850 chunk LKM::prototypes() | 2031 chunk LKM::prototypes() |
1851 { | 2032 { |
1852 @@ -226,31 +237,37 @@ | 2033 - static int rtx_ethernet_close(struct net_device *); |
2034 + static int rtx_ethernet_close(struct net_device *); | |
2035 } | |
1853 | 2036 |
1854 chunk LKM::code() | 2037 chunk LKM::code() |
1855 { | 2038 { |
1856 - static int rtx_ethernet_close(struct net_device *dev) | 2039 - static int rtx_ethernet_close(struct net_device *dev) |
1857 + static int rtx_ethernet_close(struct net_device *net_dev) | 2040 + static int rtx_ethernet_close(struct net_device *net_dev) |
1858 { | 2041 { |
1859 - ${Ethernet::AbstractDevice.ref} rtx_net_dev; | 2042 - ${Ethernet::AbstractDevice.ref} rtx_net_dev; |
1860 - { /* XXX: I end up with a placeholder if I don't open a scope */ | 2043 - { /* XXX: I end up with a placeholder if I don't open a scope */ |
1861 - ${local.rtx_net_dev.init(local.dev)}; | 2044 - ${local.rtx_net_dev.init(local.dev)}; |
1862 - } | 2045 - } |
1899 - template sequence Ethernet::interrupt_handler(Ethernet::Device dev) | 2082 - template sequence Ethernet::interrupt_handler(Ethernet::Device dev) |
1900 + template sequence Ethernet::interrupt_handler() | 2083 + template sequence Ethernet::interrupt_handler() |
1901 { | 2084 { |
1902 /* | 2085 /* |
1903 * We can't use the irqreturn_t type here because CNornm doesn't know | 2086 * We can't use the irqreturn_t type here because CNornm doesn't know |
1904 @@ -269,11 +286,16 @@ | 2087 @@ -258,29 +275,34 @@ |
2088 */ | |
2089 chunk LKM::prototypes() | |
2090 { | |
2091 - static enum irqreturn rtx_ethernet_interrupt_handler(int, void *); | |
2092 + static enum irqreturn rtx_ethernet_interrupt_handler(int, void *); | |
2093 } | |
2094 | |
2095 chunk LKM::code() | |
2096 { | |
2097 - static enum irqreturn rtx_ethernet_interrupt_handler(int irq, void *dev_id) | |
2098 + static enum irqreturn rtx_ethernet_interrupt_handler(int irq, void *dev_id) | |
2099 { | |
2100 ${Ethernet::AbstractDevice.ref} rtx_net_dev = dev_id; | |
1905 ${Ethernet::Device.ref} rtx_ether_ctx; | 2101 ${Ethernet::Device.ref} rtx_ether_ctx; |
1906 rtx_ether_ctx = ${local.rtx_net_dev.rtx_ether_ctx}; | 2102 rtx_ether_ctx = ${local.rtx_net_dev.rtx_ether_ctx}; |
1907 | 2103 |
1908 - ${pointcut ::IMPLEMENTATION(local.rtx_ether_ctx)}; | 2104 - ${pointcut ::IMPLEMENTATION(local.rtx_ether_ctx)}; |
1909 + ${pointcut Ethernet::adapter_handle_interrupt(local.rtx_ether_ctx)}; | 2105 + ${pointcut Ethernet::adapter_handle_interrupt(local.rtx_ether_ctx)}; |
1917 + { | 2113 + { |
1918 + } | 2114 + } |
1919 } | 2115 } |
1920 | 2116 |
1921 template sequence Ethernet::init() | 2117 template sequence Ethernet::init() |
1922 @@ -342,12 +364,8 @@ | 2118 { |
1923 * XXX: the asssignments/casts are here to circumvent | 2119 chunk LKM::data() |
1924 * typing issues in the compiler (see previous XXX). | 2120 { |
1925 */ | 2121 - static const struct net_device_ops rtx_ether_ops = |
2122 + static const struct net_device_ops rtx_ether_ops = | |
2123 { | |
2124 .ndo_open = rtx_ethernet_open, | |
2125 .ndo_stop = rtx_ethernet_close, | |
2126 @@ -298,64 +320,62 @@ | |
2127 */ | |
2128 chunk PCI::pci_probe_hook(PCI::Device rtx_pci_dev) | |
2129 { | |
2130 - ${Ethernet::AbstractDevice.ref} rtx_net_dev; | |
2131 - ${Ethernet::Device.ref} rtx_ether_ctx; | |
2132 + { | |
2133 + ${Ethernet::AbstractDevice.ref} rtx_net_dev; | |
2134 + ${Ethernet::Device.ref} rtx_ether_ctx; | |
2135 | |
2136 - rtx_net_dev = (${Ethernet::AbstractDevice.ref})alloc_etherdev(sizeof(*rtx_ether_ctx)); | |
2137 - if (!rtx_net_dev) | |
2138 - { | |
2139 - ${Log::info("cannot allocate the ethernet device context")}; | |
2140 - error = -ENOMEM; | |
2141 - goto fail; | |
2142 + rtx_net_dev = (${Ethernet::AbstractDevice.ref})alloc_etherdev(sizeof(*rtx_ether_ctx)); | |
2143 + if (!rtx_net_dev) | |
2144 + { | |
2145 + ${Log::info("cannot allocate the ethernet device context")}; | |
2146 + error = -ENOMEM; | |
2147 + goto fail; | |
2148 + } | |
2149 + SET_NETDEV_DEV(${local.rtx_net_dev.k_net_dev}, ${rtx_pci_dev.device}); | |
2150 + strlcpy(${local.rtx_net_dev.k_net_dev}->name, | |
2151 + ${config.ifname}, | |
2152 + sizeof(${local.rtx_net_dev.k_net_dev}->name)); | |
2153 + ${local.rtx_net_dev.k_net_dev}->irq = ${rtx_pci_dev.irq}; | |
2154 + ${local.rtx_net_dev.k_net_dev}->netdev_ops = &rtx_ether_ops; | |
2155 + | |
2156 + error = register_netdev(${local.rtx_net_dev.k_net_dev}); | |
2157 + if (error) | |
2158 + { | |
2159 + ${Log::info("cannot register the driver in the net subsystem")}; | |
2160 + goto fail; | |
2161 + } | |
2162 + | |
2163 + /* Initialize our context held by the net_device structure */ | |
2164 + /* | |
2165 + * XXX: the cast is here because the compiler resolve the | |
2166 + * type of rtx_pci_dev.pci_device to the type of | |
2167 + * rtx_pci_dev instead of the type of rtx_pci_dev.pci_device. | |
2168 + */ | |
2169 + ${PCI::AbstractDevice.ref} workaround = ${rtx_pci_dev.pci_device}; | |
2170 + ${cast local.workaround as PCI::AbstractDevice}; | |
2171 + { /* XXX: I end up with a placeholder if I don't open a scope */ | |
2172 + ${local.rtx_ether_ctx.init(local.rtx_net_dev, local.workaround)}; | |
2173 + } | |
2174 + | |
2175 + /* Register ourselves in the parent context: */ | |
2176 + /* ${rtx_pci_dev.set_context(local.rtx_ether_ctx)}; */ | |
2177 + ${rtx_pci_dev}->context = rtx_ether_ctx; | |
2178 + | |
2179 + /* | |
2180 + * XXX: the asssignments/casts are here to circumvent | |
2181 + * typing issues in the compiler (see previous XXX). | |
2182 + */ | |
2183 + unsigned char /* __iomem */ *io_addr = ${rtx_pci_dev.ioaddr}; | |
2184 + ${pointcut Ethernet::adapter_init_context(local.rtx_ether_ctx, local.io_addr)}; | |
2185 + ${pointcut Ethernet::adapter_reset(local.rtx_ether_ctx)}; | |
2186 + ${pointcut Ethernet::adapter_load_mac_address(local.rtx_ether_ctx)}; | |
2187 + memcpy(${local.rtx_ether_ctx.perm_addr}, | |
2188 + ${local.rtx_ether_ctx.dev_addr}, | |
2189 + ${local.rtx_net_dev.k_net_dev}->addr_len); | |
2190 } | |
2191 - SET_NETDEV_DEV(${local.rtx_net_dev.k_net_dev}, ${rtx_pci_dev.device}); | |
2192 - strlcpy(${local.rtx_net_dev.k_net_dev}->name, | |
2193 - ${config.ifname}, | |
2194 - sizeof(${local.rtx_net_dev.k_net_dev}->name)); | |
2195 - ${local.rtx_net_dev.k_net_dev}->irq = ${rtx_pci_dev.irq}; | |
2196 - ${local.rtx_net_dev.k_net_dev}->netdev_ops = &rtx_ether_ops; | |
2197 - | |
2198 - error = register_netdev(${local.rtx_net_dev.k_net_dev}); | |
2199 - if (error) | |
2200 - { | |
2201 - ${Log::info("cannot register the driver in the net subsystem")}; | |
2202 - goto fail; | |
2203 - } | |
2204 - | |
2205 - /* Initialize our context held by the net_device structure */ | |
2206 - /* | |
2207 - * XXX: the cast is here because the compiler resolve the | |
2208 - * type of rtx_pci_dev.pci_device to the type of | |
2209 - * rtx_pci_dev instead of the type of rtx_pci_dev.pci_device. | |
2210 - */ | |
2211 - ${PCI::AbstractDevice.ref} workaround = ${rtx_pci_dev.pci_device}; | |
2212 - ${cast local.workaround as PCI::AbstractDevice}; | |
2213 - { /* XXX: I end up with a placeholder if I don't open a scope */ | |
2214 - ${local.rtx_ether_ctx.init(local.rtx_net_dev, local.workaround)}; | |
2215 - } | |
2216 - | |
2217 - /* Register ourselves in the parent context: */ | |
2218 - /* ${rtx_pci_dev.set_context(local.rtx_ether_ctx)}; */ | |
2219 - ${rtx_pci_dev}->context = rtx_ether_ctx; | |
2220 - | |
2221 - /* | |
2222 - * XXX: the asssignments/casts are here to circumvent | |
2223 - * typing issues in the compiler (see previous XXX). | |
2224 - */ | |
1926 - int bars = ${rtx_pci_dev.bars}; | 2225 - int bars = ${rtx_pci_dev.bars}; |
1927 unsigned char /* __iomem */ *ioaddr = ${rtx_pci_dev.ioaddr}; | 2226 - unsigned char /* __iomem */ *ioaddr = ${rtx_pci_dev.ioaddr}; |
1928 - ${cast local.bars as Builtin::number}; | 2227 - ${cast local.bars as Builtin::number}; |
1929 - ${pointcut Ethernet::adapter_init_context(local.rtx_ether_ctx, | 2228 - ${pointcut Ethernet::adapter_init_context(local.rtx_ether_ctx, |
1930 - local.bars, | 2229 - local.bars, |
1931 - local.ioaddr)}; | 2230 - local.ioaddr)}; |
1932 + ${pointcut Ethernet::adapter_init_context(local.rtx_ether_ctx, local.ioaddr)}; | 2231 - ${pointcut Ethernet::adapter_reset(local.rtx_ether_ctx)}; |
1933 ${pointcut Ethernet::adapter_reset(local.rtx_ether_ctx)}; | 2232 - ${pointcut Ethernet::adapter_load_mac_address(local.rtx_ether_ctx)}; |
1934 ${pointcut Ethernet::adapter_load_mac_address(local.rtx_ether_ctx)}; | 2233 - memcpy(${local.rtx_ether_ctx.perm_addr}, |
1935 memcpy(${local.rtx_ether_ctx.perm_addr}, | 2234 - ${local.rtx_ether_ctx.dev_addr}, |
1936 @@ -355,7 +373,7 @@ | 2235 - ${local.rtx_net_dev.k_net_dev}->addr_len); |
1937 ${local.rtx_net_dev.k_net_dev}->addr_len); | |
1938 } | 2236 } |
1939 | 2237 |
1940 - /* This chunk should be removed (see #26) */ | 2238 - /* This chunk should be removed (see #26) */ |
1941 + /* XXX This chunk should be removed (see #26) */ | 2239 + /* XXX This chunk should be removed (see #26) */ |
1942 chunk ::CALL() | 2240 chunk ::CALL() |
1943 { | 2241 { |
1944 } | 2242 } |
1945 @@ -377,7 +395,7 @@ | 2243 @@ -369,15 +389,17 @@ |
1946 free_netdev(${local.rtx_net_dev.k_net_dev}); | 2244 */ |
2245 chunk PCI::pci_remove_hook(PCI::Device rtx_pci_dev) | |
2246 { | |
2247 - ${Ethernet::Device.ref} rtx_ether_ctx = ${rtx_pci_dev.rtx_drv_context}; | |
2248 - BUG_ON(!rtx_ether_ctx); | |
2249 + { | |
2250 + ${Ethernet::Device.ref} rtx_ether_ctx = ${rtx_pci_dev.rtx_drv_context}; | |
2251 + BUG_ON(!rtx_ether_ctx); | |
2252 | |
2253 - ${Ethernet::AbstractDevice.ref} rtx_net_dev = ${local.rtx_ether_ctx.net_device}; | |
2254 - unregister_netdev(${local.rtx_net_dev.k_net_dev}); | |
2255 - free_netdev(${local.rtx_net_dev.k_net_dev}); | |
2256 + ${Ethernet::AbstractDevice.ref} rtx_net_dev = ${local.rtx_ether_ctx.net_device}; | |
2257 + unregister_netdev(${local.rtx_net_dev.k_net_dev}); | |
2258 + free_netdev(${local.rtx_net_dev.k_net_dev}); | |
2259 + } | |
1947 } | 2260 } |
1948 | 2261 |
1949 - /* This chunk should be removed (see #26) */ | 2262 - /* This chunk should be removed (see #26) */ |
1950 + /* XXX This chunk should be removed (see #26) */ | 2263 + /* XXX This chunk should be removed (see #26) */ |
1951 chunk ::CALL() | 2264 chunk ::CALL() |
1952 { | 2265 { |
1953 } | 2266 } |
1954 diff --git a/rathaxes/samples/e1000/ethernet.rti b/rathaxes/samples/e1000/ethernet.rti | 2267 diff --git a/rathaxes/samples/e1000/ethernet.rti b/rathaxes/samples/e1000/ethernet.rti |
1955 old mode 100755 | |
1956 new mode 100644 | |
1957 --- a/rathaxes/samples/e1000/ethernet.rti | 2268 --- a/rathaxes/samples/e1000/ethernet.rti |
1958 +++ b/rathaxes/samples/e1000/ethernet.rti | 2269 +++ b/rathaxes/samples/e1000/ethernet.rti |
1959 @@ -2,16 +2,16 @@ | 2270 @@ -2,16 +2,16 @@ |
1960 { | 2271 { |
1961 required variable Builtin::string ifname; | 2272 required variable Builtin::string ifname; |
2056 + // Put a packet on the tx ring and signal the device: | 2367 + // Put a packet on the tx ring and signal the device: |
2057 + provided pointcut Ethernet::adapter_xmit(Ethernet::Device, Socket::SKBuff); | 2368 + provided pointcut Ethernet::adapter_xmit(Ethernet::Device, Socket::SKBuff); |
2058 } | 2369 } |
2059 | 2370 |
2060 - required sequence close(Ethernet::Device) | 2371 - required sequence close(Ethernet::Device) |
2061 + provided sequence close() | 2372 + provided sequence close() |
2062 { | 2373 { |
2063 - provided chunk LKM::prototypes(); | 2374 - provided chunk LKM::prototypes(); |
2064 - provided chunk LKM::code(); | 2375 - provided chunk LKM::code(); |
2065 + provided chunk LKM::prototypes(); | 2376 + provided chunk LKM::prototypes(); |
2066 + provided chunk LKM::code(); | 2377 + provided chunk LKM::code(); |
2106 + // dev_addr field/attribute of Ethernet::Device: | 2417 + // dev_addr field/attribute of Ethernet::Device: |
2107 provided pointcut Ethernet::adapter_load_mac_address(Ethernet::Device); | 2418 provided pointcut Ethernet::adapter_load_mac_address(Ethernet::Device); |
2108 } | 2419 } |
2109 | 2420 |
2110 diff --git a/rathaxes/samples/e1000/lkm.rtx b/rathaxes/samples/e1000/lkm.rtx | 2421 diff --git a/rathaxes/samples/e1000/lkm.rtx b/rathaxes/samples/e1000/lkm.rtx |
2111 old mode 100755 | |
2112 new mode 100644 | |
2113 --- a/rathaxes/samples/e1000/lkm.rtx | 2422 --- a/rathaxes/samples/e1000/lkm.rtx |
2114 +++ b/rathaxes/samples/e1000/lkm.rtx | 2423 +++ b/rathaxes/samples/e1000/lkm.rtx |
2115 @@ -1,40 +1,5 @@ | 2424 @@ -1,40 +1,5 @@ |
2116 device LKM use LKM, PCI, Ethernet, Log, Socket | 2425 device LKM use LKM, PCI, Ethernet, Log, Socket |
2117 { | 2426 { |
2161 + LKM::description = "Rathaxes Intel PCI Gigabit NIC sample driver"; | 2470 + LKM::description = "Rathaxes Intel PCI Gigabit NIC sample driver"; |
2162 LKM::license = "GPL"; | 2471 LKM::license = "GPL"; |
2163 | 2472 |
2164 /* | 2473 /* |
2165 diff --git a/rathaxes/samples/e1000/e1000.blt b/rathaxes/samples/e1000/old_e1000.blt | 2474 diff --git a/rathaxes/samples/e1000/e1000.blt b/rathaxes/samples/e1000/old_e1000.blt |
2166 old mode 100755 | |
2167 new mode 100644 | |
2168 copy from rathaxes/samples/e1000/e1000.blt | 2475 copy from rathaxes/samples/e1000/e1000.blt |
2169 copy to rathaxes/samples/e1000/old_e1000.blt | 2476 copy to rathaxes/samples/e1000/old_e1000.blt |
2170 --- a/rathaxes/samples/e1000/e1000.blt | 2477 --- a/rathaxes/samples/e1000/e1000.blt |
2171 +++ b/rathaxes/samples/e1000/old_e1000.blt | 2478 +++ b/rathaxes/samples/e1000/old_e1000.blt |
2172 @@ -170,14 +170,15 @@ | 2479 @@ -170,14 +170,15 @@ |
2188 + if (${DMA::map(local.rtx_ether_ctx.device, local.skbuff.data, local.skbuff.len, RTX_DMA_FROM_DEVICE)}) | 2495 + if (${DMA::map(local.rtx_ether_ctx.device, local.skbuff.data, local.skbuff.len, RTX_DMA_FROM_DEVICE)}) |
2189 { | 2496 { |
2190 ${Log::info("adapter_init_rx: cannot dma-map a skbuff for the rx ring")}; | 2497 ${Log::info("adapter_init_rx: cannot dma-map a skbuff for the rx ring")}; |
2191 goto err_skbuffs_map; | 2498 goto err_skbuffs_map; |
2192 diff --git a/rathaxes/samples/e1000/e1000.rti b/rathaxes/samples/e1000/old_e1000.rti | 2499 diff --git a/rathaxes/samples/e1000/e1000.rti b/rathaxes/samples/e1000/old_e1000.rti |
2193 old mode 100755 | |
2194 new mode 100644 | |
2195 copy from rathaxes/samples/e1000/e1000.rti | 2500 copy from rathaxes/samples/e1000/e1000.rti |
2196 copy to rathaxes/samples/e1000/old_e1000.rti | 2501 copy to rathaxes/samples/e1000/old_e1000.rti |
2197 diff --git a/rathaxes/samples/e1000/socket.blt b/rathaxes/samples/e1000/socket.blt | 2502 diff --git a/rathaxes/samples/e1000/socket.blt b/rathaxes/samples/e1000/socket.blt |
2198 old mode 100755 | |
2199 new mode 100644 | |
2200 --- a/rathaxes/samples/e1000/socket.blt | 2503 --- a/rathaxes/samples/e1000/socket.blt |
2201 +++ b/rathaxes/samples/e1000/socket.blt | 2504 +++ b/rathaxes/samples/e1000/socket.blt |
2202 @@ -22,16 +22,12 @@ | 2505 @@ -22,16 +22,12 @@ |
2203 { | 2506 { |
2204 decl data_types() | 2507 decl data_types() |
2344 + len: ((struct sk_buff *)((${self})->sk_buff))->len; | 2647 + len: ((struct sk_buff *)((${self})->sk_buff))->len; |
2345 } | 2648 } |
2346 } | 2649 } |
2347 } | 2650 } |
2348 diff --git a/rathaxes/samples/e1000/socket.rti b/rathaxes/samples/e1000/socket.rti | 2651 diff --git a/rathaxes/samples/e1000/socket.rti b/rathaxes/samples/e1000/socket.rti |
2349 old mode 100755 | |
2350 new mode 100644 | |
2351 --- a/rathaxes/samples/e1000/socket.rti | 2652 --- a/rathaxes/samples/e1000/socket.rti |
2352 +++ b/rathaxes/samples/e1000/socket.rti | 2653 +++ b/rathaxes/samples/e1000/socket.rti |
2353 @@ -12,20 +12,14 @@ | 2654 @@ -12,20 +12,14 @@ |
2354 { | 2655 { |
2355 chunk LKM::prototypes(); | 2656 chunk LKM::prototypes(); |