Mercurial > archived > louis > epitech > mq > rathaxes
comparison e1000_initialize_reception.patch @ 77:892b3bc7e43b
Wip on the RX init in the e1000 sample
author | Louis Opter <louis@lse.epitech.net> |
---|---|
date | Sun, 04 Mar 2012 18:35:43 +0100 |
parents | 51bea596df7f |
children | 501bf9cf65dc |
comparison
equal
deleted
inserted
replaced
76:51bea596df7f | 77:892b3bc7e43b |
---|---|
15 allocated individually). | 15 allocated individually). |
16 | 16 |
17 diff --git a/rathaxes/samples/e1000/e1000.blt b/rathaxes/samples/e1000/e1000.blt | 17 diff --git a/rathaxes/samples/e1000/e1000.blt b/rathaxes/samples/e1000/e1000.blt |
18 --- a/rathaxes/samples/e1000/e1000.blt | 18 --- a/rathaxes/samples/e1000/e1000.blt |
19 +++ b/rathaxes/samples/e1000/e1000.blt | 19 +++ b/rathaxes/samples/e1000/e1000.blt |
20 @@ -36,6 +36,25 @@ | 20 @@ -21,9 +21,12 @@ |
21 */ | |
22 typedef struct rtx_e1000_ctx | |
23 { | |
24 - int bars; | |
25 - unsigned char /* __iomem */ *ioaddr; | |
26 - int irq; | |
27 + int bars; | |
28 + unsigned char /* __iomem */ *ioaddr; | |
29 + int irq; | |
30 + | |
31 + /* we can't use the Rathaxes type here (#8) */ | |
32 + struct rtx_e1000_rx_ring rx_ring; | |
33 } *rtx_e1000_ctx_p; | |
34 } | |
35 | |
36 @@ -36,6 +39,78 @@ | |
21 } | 37 } |
22 } | 38 } |
23 | 39 |
24 + template type e1000::RingRx() | 40 + template type e1000::RxDescriptor() |
25 + { | 41 + { |
26 + chunk LKM::includes() | 42 + chunk LKM::includes() |
27 + { | 43 + { |
44 + typedef int ${e1000::RxDescriptor}; | |
45 + | |
46 + #include <linux/types.h> | |
28 + } | 47 + } |
29 + | 48 + |
30 + chunk ::decl() | 49 + chunk ::decl() |
31 + { | 50 + { |
51 + typedef struct rtx_e1000_rx_descriptor | |
52 + { | |
53 + /* actual types are in comments */ | |
54 + unsigned long int /* __le64 */ buff_addr; | |
55 + unsigned short /* __le16 */ length; | |
56 + unsigned short /* __le16 */ csum; | |
57 + unsigned char status; | |
58 + unsigned char errors; | |
59 + unsigned short /* __le16 */ special; | |
60 + } *rtx_e1000_rx_descriptor_p; | |
61 + } | |
62 + | |
63 + chunk ::init() | |
64 + { | |
65 + } | |
66 + | |
67 + map | |
68 + { | |
69 + } | |
70 + } | |
71 + | |
72 + template type e1000::RxRing() | |
73 + { | |
74 + chunk LKM::includes() | |
75 + { | |
76 + typedef int ${e1000::RxRing}; | |
77 + } | |
78 + | |
79 + chunk ::decl() | |
80 + { | |
81 + /* | |
82 + * - size: total size of the ring in bytes. | |
83 + * - base: address of the ring; | |
84 + * - dma_base: (physical) address of the ring where the device | |
85 + * can access it; | |
86 + * - skbuffs: array of the skbuffs associated with | |
87 + * each descriptor; | |
88 + * - dma_skbuffs: (physical) address of each skbuff | |
89 + * where the device can write the received | |
90 + * packets; | |
91 + */ | |
92 + struct rtx_e1000_rx_ring | |
93 + { | |
94 + unsigned int size; | |
95 + rtx_e1000_rx_descriptor_p base; | |
96 + void *dma_base; | |
97 + | |
98 + struct sk_buff *skbuffs[256 /* ${config.rx_ring_size} */]; | |
99 + void *dma_skbuffs[256 /* ${config.rx_ring_size} */]; | |
100 + }; | |
32 + } | 101 + } |
33 + | 102 + |
34 + chunk ::init() | 103 + chunk ::init() |
35 + { | 104 + { |
36 + } | 105 + } |
41 + } | 110 + } |
42 + | 111 + |
43 template type e1000::Register() | 112 template type e1000::Register() |
44 { | 113 { |
45 chunk LKM::includes() | 114 chunk LKM::includes() |
46 @@ -64,6 +83,9 @@ | 115 @@ -64,6 +139,9 @@ |
47 E1000_FCT = 0x00030, /* Flow Control Type */ | 116 E1000_FCT = 0x00030, /* Flow Control Type */ |
48 E1000_FCTTV = 0x00170, /* Flow Control Transmit Timer Value */ | 117 E1000_FCTTV = 0x00170, /* Flow Control Transmit Timer Value */ |
49 E1000_CRCERRS = 0x04000, /* CRC Error Count (base address of the statistic register spaces) */ | 118 E1000_CRCERRS = 0x04000, /* CRC Error Count (base address of the statistic register spaces) */ |
50 + E1000_RAL = 0x05400, /* Receive Address Low */ | 119 + E1000_RAL = 0x05400, /* Receive Address Low */ |
51 + E1000_RAH = 0x05404, /* Receive Address High */ | 120 + E1000_RAH = 0x05404, /* Receive Address High */ |
52 + E1000_MTA = 0x05200, /* Multicast Table Array */ | 121 + E1000_MTA = 0x05200, /* Multicast Table Array */ |
53 }; | 122 }; |
54 } | 123 } |
55 | 124 |
56 @@ -132,7 +154,8 @@ | 125 @@ -132,7 +210,8 @@ |
57 E1000_INTR_RXDMT0 = 0x00000010, /* rx desc min. threshold (0) */ | 126 E1000_INTR_RXDMT0 = 0x00000010, /* rx desc min. threshold (0) */ |
58 E1000_INTR_RXO = 0x00000040, /* rx overrun */ | 127 E1000_INTR_RXO = 0x00000040, /* rx overrun */ |
59 E1000_INTR_RXT0 = 0x00000080, /* rx timer intr (ring 0) */ | 128 E1000_INTR_RXT0 = 0x00000080, /* rx timer intr (ring 0) */ |
60 - E1000_INTR_MDAC = 0x00000200 /* MDIO access complete */ | 129 - E1000_INTR_MDAC = 0x00000200 /* MDIO access complete */ |
61 + E1000_INTR_MDAC = 0x00000200, /* MDIO access complete */ | 130 + E1000_INTR_MDAC = 0x00000200, /* MDIO access complete */ |
62 + E1000_RAH_AV = (1 << 31), /* Set the MAC Address as Valid */ | 131 + E1000_RAH_AV = (1 << 31), /* Set the MAC Address as Valid */ |
63 }; | 132 }; |
64 } | 133 } |
65 | 134 |
66 @@ -491,9 +514,32 @@ | 135 @@ -458,14 +537,23 @@ |
67 rtx_e1000_register_write32(&${ctx}->hw_ctx, E1000_FCAL, 0); | 136 chunk ::CALL |
68 rtx_e1000_register_write32(&${ctx}->hw_ctx, E1000_FCT, 0); | 137 { |
69 rtx_e1000_register_write32(&${ctx}->hw_ctx, E1000_FCTTV, 0); | 138 /* |
139 - * This is documented in the Intel Gigabit Ethernet Controller | |
140 - * Software Developper manual. | |
141 + * This part is documented in the Intel Gigabit Ethernet Controller | |
142 + * Software Developper manual. (You can find it in the doc/hardware | |
143 + * directory). | |
144 * | |
145 * Since this part is actually completely device specific it should | |
146 * not be written here. (but in the front-end). | |
147 */ | |
148 | |
149 /* | |
150 + * shortcut hw_ctx... maybe we should directly take an | |
151 + * e1000::Context? (but we would need to make it point back to | |
152 + * the struct net_device) | |
153 + */ | |
154 + ${e1000::Context} hw_ctx; | |
155 + hw_ctx = &${ctx}->hw_ctx; | |
156 + | |
157 + /* | |
158 * "General Configuration" (section 14.3): | |
159 * | |
160 * - CTRL.ASDE/CTRL.SLU: Let the PHY handle the speed detection & | |
161 @@ -478,22 +566,111 @@ | |
162 * - Finally, initialize all the statistic registers from | |
163 * E1000_CRCERRS to E1000_TSCTFC. | |
164 */ | |
165 - rtx_e1000_register_set32(&${ctx}->hw_ctx, E1000_CTRL, | |
166 + | |
167 + rtx_e1000_register_set32(hw_ctx, E1000_CTRL, | |
168 E1000_CMD_ASDE | | |
169 E1000_CMD_SLU); | |
170 - rtx_e1000_register_unset32(&${ctx}->hw_ctx, E1000_CTRL, | |
171 + rtx_e1000_register_unset32(hw_ctx, E1000_CTRL, | |
172 E1000_CMD_LRST | | |
173 E1000_CMD_FRCSPD | | |
174 E1000_CMD_PHY_RST | | |
175 E1000_CMD_ILOS | | |
176 E1000_CMD_VME); | |
177 - rtx_e1000_register_write32(&${ctx}->hw_ctx, E1000_FCAH, 0); | |
178 - rtx_e1000_register_write32(&${ctx}->hw_ctx, E1000_FCAL, 0); | |
179 - rtx_e1000_register_write32(&${ctx}->hw_ctx, E1000_FCT, 0); | |
180 - rtx_e1000_register_write32(&${ctx}->hw_ctx, E1000_FCTTV, 0); | |
70 - int i = 0; | 181 - int i = 0; |
182 + rtx_e1000_register_write32(hw_ctx, E1000_FCAH, 0); | |
183 + rtx_e1000_register_write32(hw_ctx, E1000_FCAL, 0); | |
184 + rtx_e1000_register_write32(hw_ctx, E1000_FCT, 0); | |
185 + rtx_e1000_register_write32(hw_ctx, E1000_FCTTV, 0); | |
71 + int i = 0; /* CNorm workaround, the init part of for isn't generated */ | 186 + int i = 0; /* CNorm workaround, the init part of for isn't generated */ |
72 for (i = 0; i != 64; ++i) | 187 for (i = 0; i != 64; ++i) |
73 rtx_e1000_register_write32(&${ctx}->hw_ctx, E1000_CRCERRS + i * 4, 0); | 188 - rtx_e1000_register_write32(&${ctx}->hw_ctx, E1000_CRCERRS + i * 4, 0); |
189 + rtx_e1000_register_write32(hw_ctx, E1000_CRCERRS + i * 4, 0); | |
74 + | 190 + |
75 + /* | 191 + /* |
76 + * Receive initialization | 192 + * Receive initialization |
77 + * | 193 + * |
78 + * - Program the receive address, in RAL/RAH; | 194 + * - Program the receive address, in RAL/RAH; |
79 + * - Initialize the Multicast Table Array; | 195 + * - Initialize the Multicast Table Array; |
80 + * - Program the interrupt mask register (done in | 196 + * - Program the interrupt mask register (done in |
81 + * e1000::activate_device_interruption); | 197 + * e1000::activate_device_interruption); |
82 + * | 198 + * - Allocate the receive descriptor ring and map it to make it |
83 + * (We should use uint{32,16}_t but CNorm doesn't know them yet) | 199 + * accessible by the device. |
84 + */ | 200 + */ |
85 + rtx_e1000_register_write32(&${ctx}->hw_ctx, E1000_RAL, | 201 + |
202 + /* (We should use uint{32,16}_t but CNorm doesn't know them yet) */ | |
203 + rtx_e1000_register_write32(hw_ctx, E1000_RAL, | |
86 + *(unsigned int *)(${ctx}->net_dev->dev_addr)); | 204 + *(unsigned int *)(${ctx}->net_dev->dev_addr)); |
87 + /* | 205 + /* |
88 + * The 16 upper bits of RAH also store the AS bits (which should be | 206 + * The 16 upper bits of RAH also store the AS bits (which should be |
89 + * 0) and the AV bit (should be 1 to set the address as valid). | 207 + * 0) and the AV bit (should be 1 to set the address as valid). |
90 + */ | 208 + */ |
91 + rtx_e1000_register_write32(&${ctx}->hw_ctx, E1000_RAH, | 209 + rtx_e1000_register_write32(hw_ctx, E1000_RAH, |
92 + *(unsigned short *)(&${ctx}->net_dev->dev_addr[4])); | 210 + *(unsigned short *)(&${ctx}->net_dev->dev_addr[4])); |
93 + rtx_e1000_register_set32(&${ctx}->hw_ctx, E1000_RAH, E1000_RAH_AV); | 211 + rtx_e1000_register_set32(hw_ctx, E1000_RAH, E1000_RAH_AV); |
212 + | |
94 + i = 0; /* CNorm workaround, the init part of for isn't generated */ | 213 + i = 0; /* CNorm workaround, the init part of for isn't generated */ |
95 + for (i = 0; i != 128; ++i) | 214 + for (i = 0; i != 128; ++i) |
96 + rtx_e1000_register_write32(&${ctx}->hw_ctx, E1000_MTA + i * 4, 0); | 215 + rtx_e1000_register_write32(hw_ctx, E1000_MTA + i * 4, 0); |
216 + | |
217 + hw_ctx->rx_ring.size = ${config.rx_ring_size} * sizeof(*hw_ctx->rx_ring.base); | |
218 + hw_ctx->rx_ring.size = ALIGN(hw_ctx->rx_ring.size, 4096); | |
219 + hw_ctx->rx_ring.base = dma_alloc_coherent(&${ctx}->pci_dev->dev, | |
220 + hw_ctx->rx_ring.size, &hw_ctx->rx_ring.dma_base, GFP_KERNEL); | |
221 + if (!hw->ctx->rx_ring.base) | |
222 + { | |
223 + ${Log::info("cannot allocate the descriptors for the Rx ring")}; | |
224 + goto err_rx_ring_alloc; | |
225 + } | |
226 + | |
227 + i = 0; | |
228 + for (i = 0; i != ${config.rx_ring_size}; ++i) | |
229 + { | |
230 + hw_ctx->rx_ring.skbuffs[i] = netdev_allock_skb(${ctx}->net_device, | |
231 + ${config.rx_buffer_len}); | |
232 + if (!hw_ctx->rx_ring.skbuffs[i]) | |
233 + { | |
234 + ${Log::info("cannot allocate a skbuff for the Rx ring")}; | |
235 + goto err_skbuffs_alloc; | |
236 + } | |
237 + hw_ctx->rx_ring.dma_skbuffs[i] = dma_map_single(&${ctx}->pci_dev->dev, | |
238 + hw_ctx->rx_ring.skbuffs[i]->data, | |
239 + ${config.rx_buffer_len}, | |
240 + DMA_FROM_DEVICE); | |
241 + if (dma_mapping_error(&${ctx}->pci_dev->dev, | |
242 + hw_ctx->rx_ring.dma_skbuffs[i])) | |
243 + { | |
244 + ${Log::info("cannot dma-map a skbuff for the Rx ring")}; | |
245 + goto err_skbuffs_map; | |
246 + } | |
247 + hw_ctx->rx_ring.base[i].buff_addr = cpu_to_le64(hw_ctx->rx_ring.dma_skbuffs[i]); | |
248 + } | |
249 + | |
250 + /* | |
251 + * Always the same problem with error handling, we don't know where | |
252 + * we are at in the "parent context": | |
253 + */ | |
254 + | |
255 + err_skbuffs_alloc: | |
256 + while (i--) | |
257 + { | |
258 + dma_unmap_single(&${ctx}->pci_dev->dev, | |
259 + hw_ctx->rx_ring.dma_skbuffs[i], | |
260 + ${config.rx_buffer_len}, | |
261 + DMA_FROM_DEVICE); | |
262 + err_skbuffs_map: | |
263 + dev_kfree_skb(hw_ctx->rx_ring.skbuffs[i]); | |
264 + } | |
265 + | |
266 + dma_free_coherent(&${ctx}->pci_dev->dev, hw_ctx->rx_ring.size, | |
267 + hw_ctx->rx_ring.base, hw_ctx->rx_ring.dma_base); | |
268 + err_rx_ring_alloc: | |
269 + return -ENOMEM; | |
270 + } | |
271 + } | |
272 + | |
273 + template sequence e1000::free_rx_tx(Ethernet::Device ctx) | |
274 + { | |
275 + chunk ::CALL | |
276 + { | |
277 + | |
97 } | 278 } |
98 } | 279 } |
99 | 280 |
100 diff --git a/rathaxes/samples/e1000/e1000.rti b/rathaxes/samples/e1000/e1000.rti | 281 diff --git a/rathaxes/samples/e1000/e1000.rti b/rathaxes/samples/e1000/e1000.rti |
101 --- a/rathaxes/samples/e1000/e1000.rti | 282 --- a/rathaxes/samples/e1000/e1000.rti |
102 +++ b/rathaxes/samples/e1000/e1000.rti | 283 +++ b/rathaxes/samples/e1000/e1000.rti |
103 @@ -1,6 +1,8 @@ | 284 @@ -1,6 +1,9 @@ |
104 interface e1000 : Socket, Ethernet, PCI, LKM | 285 interface e1000 : Socket, Ethernet, PCI, LKM |
105 { | 286 { |
106 provided type e1000::Context; | 287 provided type e1000::Context; |
107 + provided type e1000::RingRx; | 288 + provided type e1000::RxDescriptor; |
289 + provided type e1000::RxRing; | |
108 + | 290 + |
109 /* | 291 /* |
110 * These two types should actually be registers definitions in the frontend: | 292 * These two types should actually be registers definitions in the frontend: |
111 */ | 293 */ |
294 @@ -57,6 +60,11 @@ | |
295 provided chunk ::CALL; | |
296 } | |
297 | |
298 + provided sequence e1000::free_rx_tx(Ethernet::Device dev) | |
299 + { | |
300 + provided chunk ::CALL; | |
301 + } | |
302 + | |
303 provided sequence e1000::handle_interrupt(Ethernet::Device) | |
304 { | |
305 provided chunk ::CALL; | |
306 diff --git a/rathaxes/samples/e1000/ethernet.blt b/rathaxes/samples/e1000/ethernet.blt | |
307 --- a/rathaxes/samples/e1000/ethernet.blt | |
308 +++ b/rathaxes/samples/e1000/ethernet.blt | |
309 @@ -102,7 +102,7 @@ | |
310 { | |
311 static int rtx_ethernet_close(struct net_device *dev) | |
312 { | |
313 - struct rtx_ethernet_dev* rtx_ether_dev = netdev_priv(dev); | |
314 + struct rtx_ethernet_dev* rtx_ether_dev = netdev_priv(dev); | |
315 struct rtx_e1000_ctx* ctx = &rtx_ether_dev->hw_ctx; | |
316 | |
317 ${pointcut ::IMPLEMENTATION(local.rtx_ether_dev)}; | |
318 diff --git a/rathaxes/samples/e1000/lkm.rtx b/rathaxes/samples/e1000/lkm.rtx | |
319 --- a/rathaxes/samples/e1000/lkm.rtx | |
320 +++ b/rathaxes/samples/e1000/lkm.rtx | |
321 @@ -24,7 +24,17 @@ | |
322 Ethernet::close(Ethernet::Device dev) | |
323 { | |
324 Log::info("closing the device"); | |
325 + | |
326 + /* | |
327 + * Note: some calls to release resources must be done when IRQs are | |
328 + * enabled (dma_free_coherent() for example). So we have to cleanup our | |
329 + * stuff before free_interrupt_handler(). | |
330 + */ | |
331 + e1000::free_rx_tx(dev); | |
332 + Log::info("free'ed up skbuffs"); | |
333 + | |
334 e1000::free_interrupt_handler(dev); | |
335 + Log::info("interrupt handler free'ed"); | |
336 } | |
337 | |
338 Ethernet::interrupt_handler(Ethernet::Device dev) | |
339 @@ -61,4 +71,11 @@ | |
340 PCI::set_master = true; | |
341 | |
342 Ethernet::ifname = "rtx%d"; | |
343 + | |
344 + e1000::rx_ring_size = 256; /* Number of incoming packets we can buffer */ | |
345 + /* | |
346 + * The e1000 supports seven receive buffer sizes: 256, 512, 1024, 2048, | |
347 + * 4096, 8192 and 16384 bytes: | |
348 + */ | |
349 + e1000::rx_buffer_len = 2048; | |
350 } |