90 (sizeof(struct ccat_eth_frame) - max(sizeof(struct ccat_dma_frame_hdr), sizeof(struct ccat_eim_frame_hdr))) |
92 (sizeof(struct ccat_eth_frame) - max(sizeof(struct ccat_dma_frame_hdr), sizeof(struct ccat_eim_frame_hdr))) |
91 |
93 |
92 /** |
94 /** |
93 * struct ccat_eth_register - CCAT register addresses in the PCI BAR |
95 * struct ccat_eth_register - CCAT register addresses in the PCI BAR |
94 * @mii: address of the CCAT management interface register |
96 * @mii: address of the CCAT management interface register |
95 * @tx_fifo: address of the CCAT TX DMA fifo register |
|
96 * @rx_fifo: address of the CCAT RX DMA fifo register |
|
97 * @mac: address of the CCAT media access control register |
97 * @mac: address of the CCAT media access control register |
98 * @rx_mem: address of the CCAT register holding the RX DMA address |
98 * @rx_mem: address of the CCAT register holding the RX DMA address |
99 * @tx_mem: address of the CCAT register holding the TX DMA address |
99 * @tx_mem: address of the CCAT register holding the TX DMA address |
100 * @misc: address of a CCAT register holding miscellaneous information |
100 * @misc: address of a CCAT register holding miscellaneous information |
101 */ |
101 */ |
102 struct ccat_eth_register { |
102 struct ccat_eth_register { |
103 void __iomem *mii; |
103 void __iomem *mii; |
104 void __iomem *tx_fifo; |
|
105 void __iomem *rx_fifo; |
|
106 void __iomem *mac; |
104 void __iomem *mac; |
107 void __iomem *rx_mem; |
105 void __iomem *rx_mem; |
108 void __iomem *tx_mem; |
106 void __iomem *tx_mem; |
109 void __iomem *misc; |
107 void __iomem *misc; |
110 }; |
108 }; |
111 |
109 |
112 /** |
110 /** |
113 * struct ccat_dma - CCAT DMA channel configuration |
111 * struct ccat_dma_mem - CCAT DMA channel configuration |
|
112 * @size: number of bytes in the associated DMA memory |
114 * @phys: device-viewed address(physical) of the associated DMA memory |
113 * @phys: device-viewed address(physical) of the associated DMA memory |
115 * @start: CPU-viewed address(virtual) of the associated DMA memory |
|
116 * @size: number of bytes in the associated DMA memory |
|
117 * @channel: CCAT DMA channel number |
114 * @channel: CCAT DMA channel number |
118 * @dev: valid struct device pointer |
115 * @dev: valid struct device pointer |
119 */ |
116 * @base: CPU-viewed address(virtual) of the associated DMA memory |
120 struct ccat_dma { |
117 */ |
121 struct ccat_dma_frame *next; |
118 struct ccat_dma_mem { |
122 void *start; |
|
123 size_t size; |
119 size_t size; |
124 dma_addr_t phys; |
120 dma_addr_t phys; |
125 size_t channel; |
121 size_t channel; |
126 struct device *dev; |
122 struct device *dev; |
|
123 void *base; |
|
124 }; |
|
125 |
|
126 /** |
|
127 * struct ccat_dma/eim/mem |
|
128 * @next: pointer to the next frame in fifo ring buffer |
|
129 * @start: aligned CPU-viewed address(virtual) of the associated memory |
|
130 */ |
|
131 struct ccat_dma { |
|
132 struct ccat_dma_frame *next; |
|
133 void *start; |
127 }; |
134 }; |
128 |
135 |
129 struct ccat_eim { |
136 struct ccat_eim { |
130 struct ccat_eim_frame __iomem *next; |
137 struct ccat_eim_frame __iomem *next; |
131 void __iomem *start; |
138 void __iomem *start; |
132 size_t size; |
|
133 }; |
139 }; |
134 |
140 |
135 struct ccat_mem { |
141 struct ccat_mem { |
136 struct ccat_eth_frame *next; |
142 struct ccat_eth_frame *next; |
137 void *start; |
143 void *start; |
138 }; |
144 }; |
139 |
145 |
140 /** |
146 /** |
141 * struct ccat_eth_fifo - CCAT RX or TX DMA fifo |
147 * struct ccat_eth_fifo - CCAT RX or TX fifo |
142 * @add: callback used to add a frame to this fifo |
148 * @ops: function pointer table for dma/eim and rx/tx specific fifo functions |
143 * @reg: PCI register address of this DMA fifo |
149 * @reg: PCI register address of this fifo |
144 * @dma: information about the associated DMA memory |
150 * @rx_bytes: number of bytes processed -> reported with ndo_get_stats64() |
|
151 * @rx_dropped: number of dropped frames -> reported with ndo_get_stats64() |
|
152 * @mem/dma/eim: information about the associated memory |
145 */ |
153 */ |
146 struct ccat_eth_fifo { |
154 struct ccat_eth_fifo { |
147 void (*add) (struct ccat_eth_fifo *); |
155 const struct ccat_eth_fifo_operations *ops; |
148 void (*copy_to_skb) (struct ccat_eth_fifo *, struct sk_buff *, size_t); |
156 const struct ccat_eth_frame *end; |
149 void (*queue_skb) (struct ccat_eth_fifo * const, struct sk_buff *); |
|
150 void __iomem *reg; |
157 void __iomem *reg; |
151 const struct ccat_eth_frame *end; |
158 atomic64_t bytes; |
|
159 atomic64_t dropped; |
152 union { |
160 union { |
153 struct ccat_mem mem; |
161 struct ccat_mem mem; |
154 struct ccat_dma dma; |
162 struct ccat_dma dma; |
155 struct ccat_eim eim; |
163 struct ccat_eim eim; |
156 }; |
164 }; |
|
165 }; |
|
166 |
|
167 /** |
|
168 * struct ccat_eth_fifo_operations |
|
169 * @ready: callback used to test the next frames ready bit |
|
170 * @add: callback used to add a frame to this fifo |
|
171 * @copy_to_skb: callback used to copy from rx fifos to skbs |
|
172 * @skb: callback used to queue skbs into tx fifos |
|
173 */ |
|
174 struct ccat_eth_fifo_operations { |
|
175 size_t(*ready) (struct ccat_eth_fifo *); |
|
176 void (*add) (struct ccat_eth_fifo *); |
|
177 union { |
|
178 void (*copy_to_skb) (struct ccat_eth_fifo *, struct sk_buff *, |
|
179 size_t); |
|
180 void (*skb) (struct ccat_eth_fifo *, struct sk_buff *); |
|
181 } queue; |
157 }; |
182 }; |
158 |
183 |
159 /** |
184 /** |
160 * same as: typedef struct _CCatInfoBlockOffs from CCatDefinitions.h |
185 * same as: typedef struct _CCatInfoBlockOffs from CCatDefinitions.h |
161 */ |
186 */ |
171 |
196 |
172 /** |
197 /** |
173 * struct ccat_eth_priv - CCAT Ethernet/EtherCAT Master function (netdev) |
198 * struct ccat_eth_priv - CCAT Ethernet/EtherCAT Master function (netdev) |
174 * @func: pointer to the parent struct ccat_function |
199 * @func: pointer to the parent struct ccat_function |
175 * @netdev: the net_device structure used by the kernel networking stack |
200 * @netdev: the net_device structure used by the kernel networking stack |
176 * @info: holds a copy of the CCAT Ethernet/EtherCAT Master function information block (read from PCI config space) |
|
177 * @reg: register addresses in PCI config space of the Ethernet/EtherCAT Master function |
201 * @reg: register addresses in PCI config space of the Ethernet/EtherCAT Master function |
178 * @rx_fifo: DMA fifo used for RX DMA descriptors |
202 * @rx_fifo: fifo used for RX descriptors |
179 * @tx_fifo: DMA fifo used for TX DMA descriptors |
203 * @tx_fifo: fifo used for TX descriptors |
180 * @poll_timer: interval timer used to poll CCAT for events like link changed, rx done, tx done |
204 * @poll_timer: interval timer used to poll CCAT for events like link changed, rx done, tx done |
181 * @rx_bytes: number of bytes received -> reported with ndo_get_stats64() |
|
182 * @rx_dropped: number of received frames, which were dropped -> reported with ndo_get_stats64() |
|
183 * @tx_bytes: number of bytes send -> reported with ndo_get_stats64() |
|
184 * @tx_dropped: number of frames requested to send, which were dropped -> reported with ndo_get_stats64() |
|
185 */ |
205 */ |
186 struct ccat_eth_priv { |
206 struct ccat_eth_priv { |
187 void (*free) (struct ccat_eth_priv *); |
|
188 bool(*tx_ready) (const struct ccat_eth_priv *); |
|
189 size_t(*rx_ready) (struct ccat_eth_fifo *); |
|
190 struct ccat_function *func; |
207 struct ccat_function *func; |
191 struct net_device *netdev; |
208 struct net_device *netdev; |
192 struct ccat_eth_register reg; |
209 struct ccat_eth_register reg; |
193 struct ccat_eth_fifo rx_fifo; |
210 struct ccat_eth_fifo rx_fifo; |
194 struct ccat_eth_fifo tx_fifo; |
211 struct ccat_eth_fifo tx_fifo; |
195 struct hrtimer poll_timer; |
212 struct hrtimer poll_timer; |
196 atomic64_t rx_bytes; |
213 struct ccat_dma_mem dma_mem; |
197 atomic64_t rx_dropped; |
|
198 atomic64_t tx_bytes; |
|
199 atomic64_t tx_dropped; |
|
200 ec_device_t *ecdev; |
214 ec_device_t *ecdev; |
201 void (*carrier_off) (struct net_device * netdev); |
215 void (*carrier_off) (struct net_device * netdev); |
202 bool(*carrier_ok) (const struct net_device * netdev); |
216 bool(*carrier_ok) (const struct net_device * netdev); |
203 void (*carrier_on) (struct net_device * netdev); |
217 void (*carrier_on) (struct net_device * netdev); |
204 void (*kfree_skb_any) (struct sk_buff * skb); |
218 void (*kfree_skb_any) (struct sk_buff * skb); |
232 u64 reserved8[9]; |
246 u64 reserved8[9]; |
233 /** Connection @+0x78 */ |
247 /** Connection @+0x78 */ |
234 u8 mii_connected; |
248 u8 mii_connected; |
235 }; |
249 }; |
236 |
250 |
237 static void ccat_dma_free(struct ccat_dma *const dma) |
251 static void fifo_set_end(struct ccat_eth_fifo *const fifo, size_t size) |
238 { |
252 { |
239 const struct ccat_dma tmp = *dma; |
253 fifo->end = fifo->mem.start + size - sizeof(struct ccat_eth_frame); |
240 |
254 } |
241 free_dma(dma->channel); |
255 |
242 memset(dma, 0, sizeof(*dma)); |
256 static void ccat_dma_free(struct ccat_eth_priv *const priv) |
243 dma_free_coherent(tmp.dev, tmp.size, tmp.start, tmp.phys); |
257 { |
|
258 if (priv->dma_mem.base) { |
|
259 const struct ccat_dma_mem tmp = priv->dma_mem; |
|
260 |
|
261 memset(&priv->dma_mem, 0, sizeof(priv->dma_mem)); |
|
262 dma_free_coherent(tmp.dev, tmp.size, tmp.base, tmp.phys); |
|
263 free_dma(priv->func->info.tx_dma_chan); |
|
264 free_dma(priv->func->info.rx_dma_chan); |
|
265 } |
244 } |
266 } |
245 |
267 |
246 /** |
268 /** |
247 * ccat_dma_init() - Initialize CCAT and host memory for DMA transfer |
269 * ccat_dma_init() - Initialize CCAT and host memory for DMA transfer |
248 * @dma object for management data which will be initialized |
270 * @dma object for management data which will be initialized |
249 * @channel number of the DMA channel |
271 * @channel number of the DMA channel |
250 * @ioaddr of the pci bar2 configspace used to calculate the address of the pci dma configuration |
272 * @ioaddr of the pci bar2 configspace used to calculate the address of the pci dma configuration |
251 * @dev which should be configured for DMA |
273 * @dev which should be configured for DMA |
252 */ |
274 */ |
253 static int ccat_dma_init(struct ccat_dma *const dma, size_t channel, |
275 static int ccat_dma_init(struct ccat_dma_mem *const dma, size_t channel, |
254 void __iomem * const ioaddr, struct device *const dev) |
276 void __iomem * const bar2, |
255 { |
277 struct ccat_eth_fifo *const fifo) |
256 void *frame; |
278 { |
257 u64 addr; |
279 void __iomem *const ioaddr = bar2 + 0x1000 + (sizeof(u64) * channel); |
258 u32 translateAddr; |
280 const dma_addr_t phys = CCAT_ALIGN_CHANNEL(dma->phys, channel); |
259 u32 memTranslate; |
281 const u32 phys_hi = (sizeof(phys) > sizeof(u32)) ? phys >> 32 : 0; |
260 u32 memSize; |
282 fifo->dma.start = CCAT_ALIGN_CHANNEL(dma->base, channel); |
261 u32 data = 0xffffffff; |
283 |
262 u32 offset = (sizeof(u64) * channel) + 0x1000; |
284 fifo_set_end(fifo, CCAT_ALIGNMENT); |
263 |
|
264 dma->channel = channel; |
|
265 dma->dev = dev; |
|
266 |
|
267 /* calculate size and alignments */ |
|
268 iowrite32(data, ioaddr + offset); |
|
269 wmb(); |
|
270 data = ioread32(ioaddr + offset); |
|
271 memTranslate = data & 0xfffffffc; |
|
272 memSize = (~memTranslate) + 1; |
|
273 dma->size = 2 * memSize - PAGE_SIZE; |
|
274 dma->start = |
|
275 dma_zalloc_coherent(dev, dma->size, &dma->phys, GFP_KERNEL); |
|
276 if (!dma->start || !dma->phys) { |
|
277 pr_info("init DMA%llu memory failed.\n", (u64) channel); |
|
278 return -ENOMEM; |
|
279 } |
|
280 |
|
281 if (request_dma(channel, KBUILD_MODNAME)) { |
285 if (request_dma(channel, KBUILD_MODNAME)) { |
282 pr_info("request dma channel %llu failed\n", (u64) channel); |
286 pr_info("request dma channel %llu failed\n", (u64) channel); |
283 ccat_dma_free(dma); |
|
284 return -EINVAL; |
287 return -EINVAL; |
285 } |
288 } |
286 |
289 |
287 translateAddr = (dma->phys + memSize - PAGE_SIZE) & memTranslate; |
290 /** bit 0 enables 64 bit mode on ccat */ |
288 addr = translateAddr; |
291 iowrite32((u32) phys | ((phys_hi) > 0), ioaddr); |
289 memcpy_toio(ioaddr + offset, &addr, sizeof(addr)); |
292 iowrite32(phys_hi, ioaddr + 4); |
290 frame = dma->start + translateAddr - dma->phys; |
293 |
291 pr_debug |
294 pr_debug |
292 ("DMA%llu mem initialized\n start: 0x%p\n phys: 0x%llx\n translated: 0x%llx\n pci addr: 0x%08x%x\n memTranslate: 0x%x\n size: %llu bytes.\n", |
295 ("DMA%llu mem initialized\n base: 0x%p\n start: 0x%p\n phys: 0x%09llx\n pci addr: 0x%01x%08x\n size: %llu |%llx bytes.\n", |
293 (u64) channel, dma->start, (u64) (dma->phys), addr, |
296 (u64) channel, dma->base, fifo->dma.start, (u64) dma->phys, |
294 ioread32(ioaddr + offset + 4), ioread32(ioaddr + offset), |
297 ioread32(ioaddr + 4), ioread32(ioaddr), |
295 memTranslate, (u64) dma->size); |
298 (u64) dma->size, (u64) dma->size); |
296 return 0; |
299 return 0; |
297 } |
300 } |
298 |
301 |
299 static void ecdev_kfree_skb_any(struct sk_buff *skb) |
302 static void ecdev_kfree_skb_any(struct sk_buff *skb) |
300 { |
303 { |
478 addr_and_length += |
480 addr_and_length += |
479 ((skb->len + sizeof(struct ccat_dma_frame_hdr)) / 8) << 24; |
481 ((skb->len + sizeof(struct ccat_dma_frame_hdr)) / 8) << 24; |
480 iowrite32(addr_and_length, fifo->reg); |
482 iowrite32(addr_and_length, fifo->reg); |
481 } |
483 } |
482 |
484 |
483 static void ccat_eth_priv_free_dma(struct ccat_eth_priv *priv) |
485 static const struct ccat_eth_fifo_operations dma_rx_fifo_ops = { |
|
486 .add = ccat_eth_rx_fifo_dma_add, |
|
487 .ready = fifo_dma_rx_ready, |
|
488 .queue.copy_to_skb = fifo_dma_copy_to_linear_skb, |
|
489 }; |
|
490 |
|
491 static const struct ccat_eth_fifo_operations dma_tx_fifo_ops = { |
|
492 .add = ccat_eth_tx_fifo_dma_add_free, |
|
493 .ready = fifo_dma_tx_ready, |
|
494 .queue.skb = fifo_dma_queue_skb, |
|
495 }; |
|
496 |
|
497 static const struct ccat_eth_fifo_operations eim_rx_fifo_ops = { |
|
498 .add = fifo_eim_rx_add, |
|
499 .queue.copy_to_skb = fifo_eim_copy_to_linear_skb, |
|
500 .ready = fifo_eim_rx_ready, |
|
501 }; |
|
502 |
|
503 static const struct ccat_eth_fifo_operations eim_tx_fifo_ops = { |
|
504 .add = fifo_eim_tx_add, |
|
505 .queue.skb = fifo_eim_queue_skb, |
|
506 .ready = fifo_eim_tx_ready, |
|
507 }; |
|
508 |
|
509 static void ccat_eth_priv_free(struct ccat_eth_priv *priv) |
484 { |
510 { |
485 /* reset hw fifo's */ |
511 /* reset hw fifo's */ |
486 iowrite32(0, priv->rx_fifo.reg + 0x8); |
512 ccat_eth_fifo_hw_reset(&priv->rx_fifo); |
487 iowrite32(0, priv->tx_fifo.reg + 0x8); |
513 ccat_eth_fifo_hw_reset(&priv->tx_fifo); |
488 wmb(); |
|
489 |
514 |
490 /* release dma */ |
515 /* release dma */ |
491 ccat_dma_free(&priv->rx_fifo.dma); |
516 ccat_dma_free(priv); |
492 ccat_dma_free(&priv->tx_fifo.dma); |
517 } |
493 } |
518 |
494 |
519 static int ccat_hw_disable_mac_filter(struct ccat_eth_priv *priv) |
495 /** |
520 { |
496 * Initalizes both (Rx/Tx) DMA fifo's and related management structures |
|
497 */ |
|
498 static int ccat_eth_priv_init_dma(struct ccat_eth_priv *priv) |
|
499 { |
|
500 struct ccat_function *const func = priv->func; |
|
501 struct pci_dev *pdev = func->ccat->pdev; |
|
502 int status = 0; |
|
503 priv->rx_ready = fifo_dma_rx_ready; |
|
504 priv->tx_ready = fifo_dma_tx_ready; |
|
505 priv->free = ccat_eth_priv_free_dma; |
|
506 |
|
507 status = |
|
508 ccat_dma_init(&priv->rx_fifo.dma, func->info.rx_dma_chan, |
|
509 func->ccat->bar_2, &pdev->dev); |
|
510 if (status) { |
|
511 pr_info("init RX DMA memory failed.\n"); |
|
512 return status; |
|
513 } |
|
514 |
|
515 status = |
|
516 ccat_dma_init(&priv->tx_fifo.dma, func->info.tx_dma_chan, |
|
517 func->ccat->bar_2, &pdev->dev); |
|
518 if (status) { |
|
519 pr_info("init TX DMA memory failed.\n"); |
|
520 ccat_dma_free(&priv->rx_fifo.dma); |
|
521 return status; |
|
522 } |
|
523 |
|
524 priv->rx_fifo.add = ccat_eth_rx_fifo_dma_add; |
|
525 priv->rx_fifo.copy_to_skb = fifo_dma_copy_to_linear_skb; |
|
526 priv->rx_fifo.queue_skb = NULL; |
|
527 priv->rx_fifo.end = |
|
528 ((struct ccat_eth_frame *)priv->rx_fifo.dma.start) + FIFO_LENGTH - |
|
529 1; |
|
530 priv->rx_fifo.reg = priv->reg.rx_fifo; |
|
531 ccat_eth_fifo_reset(&priv->rx_fifo); |
|
532 |
|
533 priv->tx_fifo.add = ccat_eth_tx_fifo_dma_add_free; |
|
534 priv->tx_fifo.copy_to_skb = NULL; |
|
535 priv->tx_fifo.queue_skb = fifo_dma_queue_skb; |
|
536 priv->tx_fifo.end = |
|
537 ((struct ccat_eth_frame *)priv->tx_fifo.dma.start) + FIFO_LENGTH - |
|
538 1; |
|
539 priv->tx_fifo.reg = priv->reg.tx_fifo; |
|
540 ccat_eth_fifo_reset(&priv->tx_fifo); |
|
541 |
|
542 /* disable MAC filter */ |
|
543 iowrite8(0, priv->reg.mii + 0x8 + 6); |
521 iowrite8(0, priv->reg.mii + 0x8 + 6); |
544 wmb(); |
522 wmb(); |
545 return 0; |
523 return 0; |
546 } |
524 } |
547 |
525 |
|
526 /** |
|
527 * Initalizes both (Rx/Tx) DMA fifo's and related management structures |
|
528 */ |
|
529 static int ccat_eth_priv_init_dma(struct ccat_eth_priv *priv) |
|
530 { |
|
531 struct ccat_dma_mem *const dma = &priv->dma_mem; |
|
532 struct pci_dev *const pdev = priv->func->ccat->pdev; |
|
533 void __iomem *const bar_2 = priv->func->ccat->bar_2; |
|
534 const u8 rx_chan = priv->func->info.rx_dma_chan; |
|
535 const u8 tx_chan = priv->func->info.tx_dma_chan; |
|
536 int status = 0; |
|
537 |
|
538 dma->dev = &pdev->dev; |
|
539 dma->size = CCAT_ALIGNMENT * 3; |
|
540 dma->base = |
|
541 dma_zalloc_coherent(dma->dev, dma->size, &dma->phys, GFP_KERNEL); |
|
542 if (!dma->base || !dma->phys) { |
|
543 pr_err("init DMA memory failed.\n"); |
|
544 return -ENOMEM; |
|
545 } |
|
546 |
|
547 priv->rx_fifo.ops = &dma_rx_fifo_ops; |
|
548 status = ccat_dma_init(dma, rx_chan, bar_2, &priv->rx_fifo); |
|
549 if (status) { |
|
550 pr_info("init RX DMA memory failed.\n"); |
|
551 ccat_dma_free(priv); |
|
552 return status; |
|
553 } |
|
554 |
|
555 priv->tx_fifo.ops = &dma_tx_fifo_ops; |
|
556 status = ccat_dma_init(dma, tx_chan, bar_2, &priv->tx_fifo); |
|
557 if (status) { |
|
558 pr_info("init TX DMA memory failed.\n"); |
|
559 ccat_dma_free(priv); |
|
560 return status; |
|
561 } |
|
562 return ccat_hw_disable_mac_filter(priv); |
|
563 } |
|
564 |
548 static int ccat_eth_priv_init_eim(struct ccat_eth_priv *priv) |
565 static int ccat_eth_priv_init_eim(struct ccat_eth_priv *priv) |
549 { |
566 { |
550 priv->rx_ready = fifo_eim_rx_ready; |
|
551 priv->tx_ready = fifo_eim_tx_ready; |
|
552 priv->free = ccat_eth_priv_free_eim; |
|
553 |
|
554 priv->rx_fifo.eim.start = priv->reg.rx_mem; |
567 priv->rx_fifo.eim.start = priv->reg.rx_mem; |
555 priv->rx_fifo.eim.size = priv->func->info.rx_size; |
568 priv->rx_fifo.ops = &eim_rx_fifo_ops; |
556 |
569 fifo_set_end(&priv->rx_fifo, sizeof(struct ccat_eth_frame)); |
557 priv->rx_fifo.add = fifo_eim_rx_add; |
|
558 priv->rx_fifo.copy_to_skb = fifo_eim_copy_to_linear_skb; |
|
559 priv->rx_fifo.queue_skb = NULL; |
|
560 priv->rx_fifo.end = priv->rx_fifo.dma.start; |
|
561 priv->rx_fifo.reg = NULL; |
|
562 ccat_eth_fifo_reset(&priv->rx_fifo); |
|
563 |
570 |
564 priv->tx_fifo.eim.start = priv->reg.tx_mem; |
571 priv->tx_fifo.eim.start = priv->reg.tx_mem; |
565 priv->tx_fifo.eim.size = priv->func->info.tx_size; |
572 priv->tx_fifo.ops = &eim_tx_fifo_ops; |
566 |
573 fifo_set_end(&priv->tx_fifo, priv->func->info.tx_size); |
567 priv->tx_fifo.add = fifo_eim_tx_add; |
574 |
568 priv->tx_fifo.copy_to_skb = NULL; |
575 return ccat_hw_disable_mac_filter(priv); |
569 priv->tx_fifo.queue_skb = fifo_eim_queue_skb; |
|
570 priv->tx_fifo.end = |
|
571 priv->tx_fifo.dma.start + priv->tx_fifo.dma.size - |
|
572 sizeof(struct ccat_eth_frame); |
|
573 priv->tx_fifo.reg = priv->reg.tx_fifo; |
|
574 ccat_eth_fifo_reset(&priv->tx_fifo); |
|
575 |
|
576 /* disable MAC filter */ |
|
577 iowrite8(0, priv->reg.mii + 0x8 + 6); |
|
578 wmb(); |
|
579 return 0; |
|
580 } |
576 } |
581 |
577 |
582 /** |
578 /** |
583 * Initializes a struct ccat_eth_register with data from a corresponding |
579 * Initializes a struct ccat_eth_register with data from a corresponding |
584 * CCAT function. |
580 * CCAT function. |
585 */ |
581 */ |
586 static void ccat_eth_priv_init_reg(struct ccat_eth_register *const reg, |
582 static void ccat_eth_priv_init_reg(struct ccat_eth_priv *const priv) |
587 const struct ccat_function *const func) |
|
588 { |
583 { |
589 struct ccat_mac_infoblock offsets; |
584 struct ccat_mac_infoblock offsets; |
|
585 struct ccat_eth_register *const reg = &priv->reg; |
|
586 const struct ccat_function *const func = priv->func; |
590 void __iomem *const func_base = func->ccat->bar_0 + func->info.addr; |
587 void __iomem *const func_base = func->ccat->bar_0 + func->info.addr; |
591 |
588 |
592 /* struct ccat_eth_fifo contains a union of ccat_dma, ccat_eim and ccat_mem |
589 /* struct ccat_eth_fifo contains a union of ccat_dma, ccat_eim and ccat_mem |
593 * the members next, start and size have to overlay the exact same memory, |
590 * the members next and start have to overlay the exact same memory, |
594 * to support 'polymorphic' usage of them */ |
591 * to support 'polymorphic' usage of them */ |
595 BUILD_BUG_ON(offsetof(struct ccat_dma, next) != |
592 BUILD_BUG_ON(offsetof(struct ccat_dma, next) != |
596 offsetof(struct ccat_mem, next)); |
593 offsetof(struct ccat_mem, next)); |
597 BUILD_BUG_ON(offsetof(struct ccat_dma, start) != |
594 BUILD_BUG_ON(offsetof(struct ccat_dma, start) != |
598 offsetof(struct ccat_mem, start)); |
595 offsetof(struct ccat_mem, start)); |
599 BUILD_BUG_ON(offsetof(struct ccat_dma, next) != |
596 BUILD_BUG_ON(offsetof(struct ccat_dma, next) != |
600 offsetof(struct ccat_eim, next)); |
597 offsetof(struct ccat_eim, next)); |
601 BUILD_BUG_ON(offsetof(struct ccat_dma, start) != |
598 BUILD_BUG_ON(offsetof(struct ccat_dma, start) != |
602 offsetof(struct ccat_eim, start)); |
599 offsetof(struct ccat_eim, start)); |
603 BUILD_BUG_ON(offsetof(struct ccat_dma, size) != |
|
604 offsetof(struct ccat_eim, size)); |
|
605 |
600 |
606 memcpy_fromio(&offsets, func_base, sizeof(offsets)); |
601 memcpy_fromio(&offsets, func_base, sizeof(offsets)); |
607 reg->mii = func_base + offsets.mii; |
602 reg->mii = func_base + offsets.mii; |
608 reg->tx_fifo = func_base + offsets.tx_fifo; |
603 priv->tx_fifo.reg = func_base + offsets.tx_fifo; |
609 reg->rx_fifo = func_base + offsets.tx_fifo + 0x10; |
604 priv->rx_fifo.reg = func_base + offsets.tx_fifo + 0x10; |
610 reg->mac = func_base + offsets.mac; |
605 reg->mac = func_base + offsets.mac; |
611 reg->rx_mem = func_base + offsets.rx_mem; |
606 reg->rx_mem = func_base + offsets.rx_mem; |
612 reg->tx_mem = func_base + offsets.tx_mem; |
607 reg->tx_mem = func_base + offsets.tx_mem; |
613 reg->misc = func_base + offsets.misc; |
608 reg->misc = func_base + offsets.misc; |
614 } |
609 } |
619 struct ccat_eth_priv *const priv = netdev_priv(dev); |
614 struct ccat_eth_priv *const priv = netdev_priv(dev); |
620 struct ccat_eth_fifo *const fifo = &priv->tx_fifo; |
615 struct ccat_eth_fifo *const fifo = &priv->tx_fifo; |
621 |
616 |
622 if (skb_is_nonlinear(skb)) { |
617 if (skb_is_nonlinear(skb)) { |
623 pr_warn("Non linear skb not supported -> drop frame.\n"); |
618 pr_warn("Non linear skb not supported -> drop frame.\n"); |
624 atomic64_inc(&priv->tx_dropped); |
619 atomic64_inc(&fifo->dropped); |
625 priv->kfree_skb_any(skb); |
620 priv->kfree_skb_any(skb); |
626 return NETDEV_TX_OK; |
621 return NETDEV_TX_OK; |
627 } |
622 } |
628 |
623 |
629 if (skb->len > MAX_PAYLOAD_SIZE) { |
624 if (skb->len > MAX_PAYLOAD_SIZE) { |
630 pr_warn("skb.len %llu exceeds dma buffer %llu -> drop frame.\n", |
625 pr_warn("skb.len %llu exceeds dma buffer %llu -> drop frame.\n", |
631 (u64) skb->len, (u64) MAX_PAYLOAD_SIZE); |
626 (u64) skb->len, (u64) MAX_PAYLOAD_SIZE); |
632 atomic64_inc(&priv->tx_dropped); |
627 atomic64_inc(&fifo->dropped); |
633 priv->kfree_skb_any(skb); |
628 priv->kfree_skb_any(skb); |
634 return NETDEV_TX_OK; |
629 return NETDEV_TX_OK; |
635 } |
630 } |
636 |
631 |
637 if (!priv->tx_ready(priv)) { |
632 if (!fifo->ops->ready(fifo)) { |
638 netdev_err(dev, "BUG! Tx Ring full when queue awake!\n"); |
633 netdev_err(dev, "BUG! Tx Ring full when queue awake!\n"); |
639 priv->stop_queue(priv->netdev); |
634 priv->stop_queue(priv->netdev); |
640 return NETDEV_TX_BUSY; |
635 return NETDEV_TX_BUSY; |
641 } |
636 } |
642 |
637 |
643 /* prepare frame in DMA memory */ |
638 /* prepare frame in DMA memory */ |
644 fifo->queue_skb(fifo, skb); |
639 fifo->ops->queue.skb(fifo, skb); |
645 |
640 |
646 /* update stats */ |
641 /* update stats */ |
647 atomic64_add(skb->len, &priv->tx_bytes); |
642 atomic64_add(skb->len, &fifo->bytes); |
648 |
643 |
649 priv->kfree_skb_any(skb); |
644 priv->kfree_skb_any(skb); |
650 |
645 |
651 ccat_eth_fifo_inc(fifo); |
646 ccat_eth_fifo_inc(fifo); |
652 /* stop queue if tx ring is full */ |
647 /* stop queue if tx ring is full */ |
653 |
648 if (!fifo->ops->ready(fifo)) { |
654 if (!priv->tx_ready(priv)) { |
|
655 priv->stop_queue(priv->netdev); |
649 priv->stop_queue(priv->netdev); |
656 } |
650 } |
657 return NETDEV_TX_OK; |
651 return NETDEV_TX_OK; |
658 } |
652 } |
659 |
653 |
789 { |
783 { |
790 struct ccat_eth_priv *const priv = |
784 struct ccat_eth_priv *const priv = |
791 container_of(timer, struct ccat_eth_priv, poll_timer); |
785 container_of(timer, struct ccat_eth_priv, poll_timer); |
792 |
786 |
793 poll_link(priv); |
787 poll_link(priv); |
794 if (!priv->ecdev) { |
788 poll_rx(priv); |
795 poll_rx(priv); |
789 poll_tx(priv); |
796 poll_tx(priv); |
|
797 } |
|
798 hrtimer_forward_now(timer, POLL_TIME); |
790 hrtimer_forward_now(timer, POLL_TIME); |
799 return HRTIMER_RESTART; |
791 return HRTIMER_RESTART; |
800 } |
792 } |
801 |
793 |
802 static struct rtnl_link_stats64 *ccat_eth_get_stats64(struct net_device *dev, struct rtnl_link_stats64 |
794 static struct rtnl_link_stats64 *ccat_eth_get_stats64(struct net_device *dev, struct rtnl_link_stats64 |
803 *storage) |
795 *storage) |
804 { |
796 { |
805 struct ccat_eth_priv *const priv = netdev_priv(dev); |
797 struct ccat_eth_priv *const priv = netdev_priv(dev); |
806 struct ccat_mac_register mac; |
798 struct ccat_mac_register mac; |
|
799 |
807 memcpy_fromio(&mac, priv->reg.mac, sizeof(mac)); |
800 memcpy_fromio(&mac, priv->reg.mac, sizeof(mac)); |
808 storage->rx_packets = mac.rx_frames; /* total packets received */ |
801 storage->rx_packets = mac.rx_frames; /* total packets received */ |
809 storage->tx_packets = mac.tx_frames; /* total packets transmitted */ |
802 storage->tx_packets = mac.tx_frames; /* total packets transmitted */ |
810 storage->rx_bytes = atomic64_read(&priv->rx_bytes); /* total bytes received */ |
803 storage->rx_bytes = atomic64_read(&priv->rx_fifo.bytes); /* total bytes received */ |
811 storage->tx_bytes = atomic64_read(&priv->tx_bytes); /* total bytes transmitted */ |
804 storage->tx_bytes = atomic64_read(&priv->tx_fifo.bytes); /* total bytes transmitted */ |
812 storage->rx_errors = mac.frame_len_err + mac.rx_mem_full + mac.crc_err + mac.rx_err; /* bad packets received */ |
805 storage->rx_errors = mac.frame_len_err + mac.rx_mem_full + mac.crc_err + mac.rx_err; /* bad packets received */ |
813 storage->tx_errors = mac.tx_mem_full; /* packet transmit problems */ |
806 storage->tx_errors = mac.tx_mem_full; /* packet transmit problems */ |
814 storage->rx_dropped = atomic64_read(&priv->rx_dropped); /* no space in linux buffers */ |
807 storage->rx_dropped = atomic64_read(&priv->rx_fifo.dropped); /* no space in linux buffers */ |
815 storage->tx_dropped = atomic64_read(&priv->tx_dropped); /* no space available in linux */ |
808 storage->tx_dropped = atomic64_read(&priv->tx_fifo.dropped); /* no space available in linux */ |
816 //TODO __u64 multicast; /* multicast packets received */ |
809 //TODO __u64 multicast; /* multicast packets received */ |
817 //TODO __u64 collisions; |
810 //TODO __u64 collisions; |
818 |
811 |
819 /* detailed rx_errors: */ |
812 /* detailed rx_errors: */ |
820 storage->rx_length_errors = mac.frame_len_err; |
813 storage->rx_length_errors = mac.frame_len_err; |
895 |
892 |
896 /* It would be more intuitive to check for: |
893 /* It would be more intuitive to check for: |
897 * if (priv->func->drv->type == CCATINFO_ETHERCAT_MASTER_DMA) { |
894 * if (priv->func->drv->type == CCATINFO_ETHERCAT_MASTER_DMA) { |
898 * unfortunately priv->func->drv is not initialized until probe() returns. |
895 * unfortunately priv->func->drv is not initialized until probe() returns. |
899 * So we check if there is a rx dma fifo registered to determine dma/io mode */ |
896 * So we check if there is a rx dma fifo registered to determine dma/io mode */ |
900 if (priv->rx_fifo.reg) { |
897 if (&dma_rx_fifo_ops == priv->rx_fifo.ops) { |
901 priv->receive = ecdev_receive_dma; |
898 priv->receive = ecdev_receive_dma; |
902 } else { |
899 } else { |
903 priv->receive = ecdev_receive_eim; |
900 priv->receive = ecdev_receive_eim; |
904 } |
901 } |
905 priv->start_queue = ecdev_nop; |
902 priv->start_queue = ecdev_nop; |
906 priv->stop_queue = ecdev_nop; |
903 priv->stop_queue = ecdev_nop; |
907 priv->unregister = unregister_ecdev; |
904 priv->unregister = unregister_ecdev; |
908 priv->ecdev = ecdev_offer(priv->netdev, ec_poll_rx, THIS_MODULE); |
905 priv->ecdev = ecdev_offer(priv->netdev, ec_poll, THIS_MODULE); |
909 if (priv->ecdev) { |
906 if (priv->ecdev) { |
910 priv->carrier_off(priv->netdev); |
907 priv->carrier_off(priv->netdev); |
911 if (ecdev_open(priv->ecdev)) { |
908 if (ecdev_open(priv->ecdev)) { |
912 pr_info("unable to register network device.\n"); |
909 pr_info("unable to register network device.\n"); |
913 ecdev_withdraw(priv->ecdev); |
910 ecdev_withdraw(priv->ecdev); |
914 priv->free(priv); |
911 ccat_eth_priv_free(priv); |
915 free_netdev(priv->netdev); |
912 free_netdev(priv->netdev); |
916 return -1; // TODO return better error code |
913 return -1; // TODO return better error code |
917 } |
914 } |
918 priv->func->private_data = priv; |
915 priv->func->private_data = priv; |
919 return 0; |
916 return 0; |