blob: 2b472c898c85475e5bae38be49f6c10c9229cbbd [file] [log] [blame]
David Woodhouse9c540042008-12-23 04:09:02 +00001/*
2 * Driver for the Solos PCI ADSL2+ card, designed to support Linux by
3 * Traverse Technologies -- http://www.traverse.com.au/
4 * Xrio Limited -- http://www.xrio.com/
5 *
6 *
7 * Copyright © 2008 Traverse Technologies
8 * Copyright © 2008 Intel Corporation
9 *
10 * Authors: Nathan Williams <nathan@traverse.com.au>
11 * David Woodhouse <dwmw2@infradead.org>
Simon Farnsworth7c4015b2009-01-21 20:45:49 +000012 * Treker Chen <treker@xrio.com>
David Woodhouse9c540042008-12-23 04:09:02 +000013 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * version 2, as published by the Free Software Foundation.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 */
23
24#define DEBUG
25#define VERBOSE_DEBUG
26
27#include <linux/interrupt.h>
28#include <linux/module.h>
29#include <linux/kernel.h>
30#include <linux/errno.h>
31#include <linux/ioport.h>
32#include <linux/types.h>
33#include <linux/pci.h>
34#include <linux/atm.h>
35#include <linux/atmdev.h>
36#include <linux/skbuff.h>
37#include <linux/sysfs.h>
38#include <linux/device.h>
39#include <linux/kobject.h>
Simon Farnsworth7c4015b2009-01-21 20:45:49 +000040#include <linux/firmware.h>
David Woodhouse9c540042008-12-23 04:09:02 +000041
Simon Farnsworth7c4015b2009-01-21 20:45:49 +000042#define VERSION "0.07"
David Woodhouse9c540042008-12-23 04:09:02 +000043#define PTAG "solos-pci"
44
45#define CONFIG_RAM_SIZE 128
46#define FLAGS_ADDR 0x7C
47#define IRQ_EN_ADDR 0x78
48#define FPGA_VER 0x74
49#define IRQ_CLEAR 0x70
Simon Farnsworth7c4015b2009-01-21 20:45:49 +000050#define WRITE_FLASH 0x6C
51#define PORTS 0x68
52#define FLASH_BLOCK 0x64
53#define FLASH_BUSY 0x60
54#define FPGA_MODE 0x5C
55#define FLASH_MODE 0x58
David Woodhouse9c540042008-12-23 04:09:02 +000056
57#define DATA_RAM_SIZE 32768
58#define BUF_SIZE 4096
Simon Farnsworth7c4015b2009-01-21 20:45:49 +000059#define FPGA_PAGE 528 /* FPGA flash page size*/
60#define SOLOS_PAGE 512 /* Solos flash page size*/
61#define FPGA_BLOCK (FPGA_PAGE * 8) /* FPGA flash block size*/
62#define SOLOS_BLOCK (SOLOS_PAGE * 8) /* Solos flash block size*/
David Woodhouse9c540042008-12-23 04:09:02 +000063
64#define RX_BUF(card, nr) ((card->buffers) + (nr)*BUF_SIZE*2)
65#define TX_BUF(card, nr) ((card->buffers) + (nr)*BUF_SIZE*2 + BUF_SIZE)
66
67static int debug = 0;
68static int atmdebug = 0;
Simon Farnsworth7c4015b2009-01-21 20:45:49 +000069static int firmware_upgrade = 0;
70static int fpga_upgrade = 0;
David Woodhouse9c540042008-12-23 04:09:02 +000071
72struct pkt_hdr {
73 __le16 size;
74 __le16 vpi;
75 __le16 vci;
76 __le16 type;
77};
78
79#define PKT_DATA 0
80#define PKT_COMMAND 1
81#define PKT_POPEN 3
82#define PKT_PCLOSE 4
83
84struct solos_card {
85 void __iomem *config_regs;
86 void __iomem *buffers;
87 int nr_ports;
88 struct pci_dev *dev;
89 struct atm_dev *atmdev[4];
90 struct tasklet_struct tlet;
91 spinlock_t tx_lock;
92 spinlock_t tx_queue_lock;
93 spinlock_t cli_queue_lock;
94 struct sk_buff_head tx_queue[4];
95 struct sk_buff_head cli_queue[4];
Simon Farnsworth7c4015b2009-01-21 20:45:49 +000096 int flash_chip;
David Woodhouse9c540042008-12-23 04:09:02 +000097};
98
99#define SOLOS_CHAN(atmdev) ((int)(unsigned long)(atmdev)->phy_data)
100
101MODULE_AUTHOR("Traverse Technologies <support@traverse.com.au>");
102MODULE_DESCRIPTION("Solos PCI driver");
103MODULE_VERSION(VERSION);
104MODULE_LICENSE("GPL");
105MODULE_PARM_DESC(debug, "Enable Loopback");
106MODULE_PARM_DESC(atmdebug, "Print ATM data");
Simon Farnsworth7c4015b2009-01-21 20:45:49 +0000107MODULE_PARM_DESC(firmware_upgrade, "Initiate Solos firmware upgrade");
108MODULE_PARM_DESC(fpga_upgrade, "Initiate FPGA upgrade");
David Woodhouse9c540042008-12-23 04:09:02 +0000109module_param(debug, int, 0444);
Simon Farnsworth4306cad2009-01-19 21:19:29 +0000110module_param(atmdebug, int, 0644);
Simon Farnsworth7c4015b2009-01-21 20:45:49 +0000111module_param(firmware_upgrade, int, 0444);
112module_param(fpga_upgrade, int, 0444);
David Woodhouse9c540042008-12-23 04:09:02 +0000113
114static int opens;
Simon Farnsworth7c4015b2009-01-21 20:45:49 +0000115static struct firmware *fw;
116static int flash_offset;
David Woodhouse9c540042008-12-23 04:09:02 +0000117
Simon Farnsworth7c4015b2009-01-21 20:45:49 +0000118void flash_upgrade(struct solos_card *);
119void flash_write(struct solos_card *);
David Woodhouse9c540042008-12-23 04:09:02 +0000120static void fpga_queue(struct solos_card *card, int port, struct sk_buff *skb,
121 struct atm_vcc *vcc);
122static int fpga_tx(struct solos_card *);
123static irqreturn_t solos_irq(int irq, void *dev_id);
124static struct atm_vcc* find_vcc(struct atm_dev *dev, short vpi, int vci);
125static int list_vccs(int vci);
126static int atm_init(struct solos_card *);
127static void atm_remove(struct solos_card *);
128static int send_command(struct solos_card *card, int dev, const char *buf, size_t size);
129static void solos_bh(unsigned long);
130static int print_buffer(struct sk_buff *buf);
131
132static inline void solos_pop(struct atm_vcc *vcc, struct sk_buff *skb)
133{
134 if (vcc->pop)
135 vcc->pop(vcc, skb);
136 else
137 dev_kfree_skb_any(skb);
138}
139
140static ssize_t console_show(struct device *dev, struct device_attribute *attr,
141 char *buf)
142{
143 struct atm_dev *atmdev = container_of(dev, struct atm_dev, class_dev);
144 struct solos_card *card = atmdev->dev_data;
145 struct sk_buff *skb;
146
147 spin_lock(&card->cli_queue_lock);
148 skb = skb_dequeue(&card->cli_queue[SOLOS_CHAN(atmdev)]);
149 spin_unlock(&card->cli_queue_lock);
150 if(skb == NULL)
151 return sprintf(buf, "No data.\n");
152
153 memcpy(buf, skb->data, skb->len);
154 dev_dbg(&card->dev->dev, "len: %d\n", skb->len);
155
156 kfree_skb(skb);
157 return skb->len;
158}
159
160static int send_command(struct solos_card *card, int dev, const char *buf, size_t size)
161{
162 struct sk_buff *skb;
163 struct pkt_hdr *header;
164
165// dev_dbg(&card->dev->dev, "size: %d\n", size);
166
167 if (size > (BUF_SIZE - sizeof(*header))) {
168 dev_dbg(&card->dev->dev, "Command is too big. Dropping request\n");
169 return 0;
170 }
171 skb = alloc_skb(size + sizeof(*header), GFP_ATOMIC);
172 if (!skb) {
173 dev_warn(&card->dev->dev, "Failed to allocate sk_buff in send_command()\n");
174 return 0;
175 }
176
177 header = (void *)skb_put(skb, sizeof(*header));
178
179 header->size = cpu_to_le16(size);
180 header->vpi = cpu_to_le16(0);
181 header->vci = cpu_to_le16(0);
182 header->type = cpu_to_le16(PKT_COMMAND);
183
184 memcpy(skb_put(skb, size), buf, size);
185
186 fpga_queue(card, dev, skb, NULL);
187
188 return 0;
189}
190
191static ssize_t console_store(struct device *dev, struct device_attribute *attr,
192 const char *buf, size_t count)
193{
194 struct atm_dev *atmdev = container_of(dev, struct atm_dev, class_dev);
195 struct solos_card *card = atmdev->dev_data;
196 int err;
197
198 err = send_command(card, SOLOS_CHAN(atmdev), buf, count);
199
200 return err?:count;
201}
202
203static DEVICE_ATTR(console, 0644, console_show, console_store);
204
Simon Farnsworth7c4015b2009-01-21 20:45:49 +0000205void flash_upgrade(struct solos_card *card){
206 uint32_t data32 = 0;
207 int blocksize = 0;
208 int numblocks = 0;
209 dev_info(&card->dev->dev, "Flash upgrade started\n");
210 if (card->flash_chip == 0) {
211 if (request_firmware((const struct firmware **)&fw,
212 "solos-FPGA.bin",&card->dev->dev))
213 {
214 dev_info(&card->dev->dev,
215 "Failed to find firmware\n");
216 return;
217 }
218 blocksize = FPGA_BLOCK;
219 } else {
220 if (request_firmware((const struct firmware **)&fw,
221 "solos-Firmware.bin",&card->dev->dev))
222 {
223 dev_info(&card->dev->dev,
224 "Failed to find firmware\n");
225 return;
226 }
227 blocksize = SOLOS_BLOCK;
228 }
229 numblocks = fw->size/blocksize;
230 dev_info(&card->dev->dev, "Firmware size: %d\n", fw->size);
231 dev_info(&card->dev->dev, "Number of blocks: %d\n", numblocks);
232
233
234 dev_info(&card->dev->dev, "Changing FPGA to Update mode\n");
235 iowrite32(1, card->config_regs + FPGA_MODE);
236 data32 = ioread32(card->config_regs + FPGA_MODE);
237 /*Set mode to Chip Erase*/
238 if (card->flash_chip == 0) {
239 dev_info(&card->dev->dev,
240 "Set FPGA Flash mode to FPGA Chip Erase\n");
241 } else {
242 dev_info(&card->dev->dev,
243 "Set FPGA Flash mode to Solos Chip Erase\n");
244 }
245 iowrite32((card->flash_chip * 2), card->config_regs + FLASH_MODE);
246 flash_offset = 0;
247 iowrite32(1, card->config_regs + WRITE_FLASH);
248 return;
249}
250
251void flash_write(struct solos_card *card){
252 int block;
253 int block_num;
254 int blocksize;
255 int i;
256 uint32_t data32 = 0;
257
258 /*Clear write flag*/
259 iowrite32(0, card->config_regs + WRITE_FLASH);
260 /*Set mode to Block Write*/
261 /*dev_info(&card->dev->dev, "Set FPGA Flash mode to Block Write\n");*/
262 iowrite32(((card->flash_chip * 2) + 1), card->config_regs + FLASH_MODE);
263
264 /*When finished programming flash, release firmware and exit*/
265 if (fw->size - flash_offset == 0) {
266 //release_firmware(fw); /* This crashes for some reason */
267 iowrite32(0, card->config_regs + WRITE_FLASH);
268 iowrite32(0, card->config_regs + FPGA_MODE);
269 iowrite32(0, card->config_regs + FLASH_MODE);
270 dev_info(&card->dev->dev, "Returning FPGA to Data mode\n");
271 return;
272 }
273 if (card->flash_chip == 0) {
274 blocksize = FPGA_BLOCK;
275 } else {
276 blocksize = SOLOS_BLOCK;
277 }
278
279 /*Calculate block size*/
280 if ((fw->size - flash_offset) > blocksize) {
281 block = blocksize;
282 } else {
283 block = fw->size - flash_offset;
284 }
285 block_num = flash_offset / blocksize;
286 //dev_info(&card->dev->dev, "block %d/%d\n",block_num + 1,(fw->size/512/8));
287
288 /*Copy block into RAM*/
289 for(i=0;i<block;i++){
290 if(i%4 == 0){
291 //dev_info(&card->dev->dev, "i: %d\n", i);
292 data32=0x00000000;
293 }
294
295 switch(i%4){
296 case 0:
297 data32 |= 0x0000FF00 &
298 (*(fw->data + i + flash_offset) << 8);
299 break;
300 case 1:
301 data32 |= 0x000000FF & *(fw->data + i + flash_offset);
302 break;
303 case 2:
304 data32 |= 0xFF000000 &
305 (*(fw->data + i + flash_offset) << 24);
306 break;
307 case 3:
308 data32 |= 0x00FF0000 &
309 (*(fw->data + i + flash_offset) << 16);
310 break;
311 }
312
313 if (i%4 == 3) {
314 iowrite32(data32, RX_BUF(card, 3) + i - 3);
315 }
316 }
317 i--;
318 if (i%4 != 3) {
319 iowrite32(data32, RX_BUF(card, 3) + i - (i%4));
320 }
321
322 /*Specify block number and then trigger flash write*/
323 iowrite32(block_num, card->config_regs + FLASH_BLOCK);
324 iowrite32(1, card->config_regs + WRITE_FLASH);
325// iowrite32(0, card->config_regs + WRITE_FLASH);
326 flash_offset += block;
327 return;
328}
329
David Woodhouse9c540042008-12-23 04:09:02 +0000330static irqreturn_t solos_irq(int irq, void *dev_id)
331{
332 struct solos_card *card = dev_id;
333 int handled = 1;
334
335 //ACK IRQ
336 iowrite32(0, card->config_regs + IRQ_CLEAR);
337 //Disable IRQs from FPGA
338 iowrite32(0, card->config_regs + IRQ_EN_ADDR);
339
340 /* If we only do it when the device is open, we lose console
341 messages */
342 if (1 || opens)
343 tasklet_schedule(&card->tlet);
344
345 //Enable IRQs from FPGA
346 iowrite32(1, card->config_regs + IRQ_EN_ADDR);
347 return IRQ_RETVAL(handled);
348}
349
350void solos_bh(unsigned long card_arg)
351{
352 struct solos_card *card = (void *)card_arg;
353 int port;
354 uint32_t card_flags;
355 uint32_t tx_mask;
356 uint32_t rx_done = 0;
Simon Farnsworth7c4015b2009-01-21 20:45:49 +0000357 uint32_t data32;
358
359 data32 = ioread32(card->config_regs + FPGA_MODE);
360 if (data32 != 0) {
361 data32 = ioread32(card->config_regs + FLASH_BUSY);
362 if (data32 == 0) {
363 flash_write(card);
364 }
365 return;
366 }
367
David Woodhouse9c540042008-12-23 04:09:02 +0000368
369 card_flags = ioread32(card->config_regs + FLAGS_ADDR);
370
371 /* The TX bits are set if the channel is busy; clear if not. We want to
372 invoke fpga_tx() unless _all_ the bits for active channels are set */
373 tx_mask = (1 << card->nr_ports) - 1;
374 if ((card_flags & tx_mask) != tx_mask)
375 fpga_tx(card);
376
377 for (port = 0; port < card->nr_ports; port++) {
378 if (card_flags & (0x10 << port)) {
379 struct pkt_hdr header;
380 struct sk_buff *skb;
381 struct atm_vcc *vcc;
382 int size;
383
384 rx_done |= 0x10 << port;
385
386 memcpy_fromio(&header, RX_BUF(card, port), sizeof(header));
387
388 size = le16_to_cpu(header.size);
389
390 skb = alloc_skb(size, GFP_ATOMIC);
391 if (!skb) {
392 if (net_ratelimit())
393 dev_warn(&card->dev->dev, "Failed to allocate sk_buff for RX\n");
394 continue;
395 }
396
397 memcpy_fromio(skb_put(skb, size),
398 RX_BUF(card, port) + sizeof(header),
399 size);
400
401 if (atmdebug) {
402 dev_info(&card->dev->dev, "Received: device %d\n", port);
403 dev_info(&card->dev->dev, "size: %d VPI: %d VCI: %d\n",
404 size, le16_to_cpu(header.vpi),
405 le16_to_cpu(header.vci));
406 print_buffer(skb);
407 }
408
409 switch (le16_to_cpu(header.type)) {
410 case PKT_DATA:
411 vcc = find_vcc(card->atmdev[port], le16_to_cpu(header.vpi),
412 le16_to_cpu(header.vci));
413 if (!vcc) {
414 if (net_ratelimit())
415 dev_warn(&card->dev->dev, "Received packet for unknown VCI.VPI %d.%d on port %d\n",
416 le16_to_cpu(header.vci), le16_to_cpu(header.vpi),
417 port);
418 continue;
419 }
420 atm_charge(vcc, skb->truesize);
421 vcc->push(vcc, skb);
422 atomic_inc(&vcc->stats->rx);
423 break;
424
425 case PKT_COMMAND:
426 default: /* FIXME: Not really, surely? */
427 spin_lock(&card->cli_queue_lock);
428 if (skb_queue_len(&card->cli_queue[port]) > 10) {
429 if (net_ratelimit())
430 dev_warn(&card->dev->dev, "Dropping console response on port %d\n",
431 port);
432 } else
433 skb_queue_tail(&card->cli_queue[port], skb);
434 spin_unlock(&card->cli_queue_lock);
435 break;
436 }
437 }
438 }
439 if (rx_done)
440 iowrite32(rx_done, card->config_regs + FLAGS_ADDR);
441
442 return;
443}
444
445static struct atm_vcc *find_vcc(struct atm_dev *dev, short vpi, int vci)
446{
447 struct hlist_head *head;
448 struct atm_vcc *vcc = NULL;
449 struct hlist_node *node;
450 struct sock *s;
451
452 read_lock(&vcc_sklist_lock);
453 head = &vcc_hash[vci & (VCC_HTABLE_SIZE -1)];
454 sk_for_each(s, node, head) {
455 vcc = atm_sk(s);
456 if (vcc->dev == dev && vcc->vci == vci &&
457 vcc->vpi == vpi && vcc->qos.rxtp.traffic_class != ATM_NONE)
458 goto out;
459 }
460 vcc = NULL;
461 out:
462 read_unlock(&vcc_sklist_lock);
463 return vcc;
464}
465
466static int list_vccs(int vci)
467{
468 struct hlist_head *head;
469 struct atm_vcc *vcc;
470 struct hlist_node *node;
471 struct sock *s;
472 int num_found = 0;
473 int i;
474
475 read_lock(&vcc_sklist_lock);
476 if (vci != 0){
477 head = &vcc_hash[vci & (VCC_HTABLE_SIZE -1)];
478 sk_for_each(s, node, head) {
479 num_found ++;
480 vcc = atm_sk(s);
481 printk(KERN_DEBUG "Device: %d Vpi: %d Vci: %d\n",
482 vcc->dev->number,
483 vcc->vpi,
484 vcc->vci);
485 }
486 } else {
487 for(i=0; i<32; i++){
488 head = &vcc_hash[i];
489 sk_for_each(s, node, head) {
490 num_found ++;
491 vcc = atm_sk(s);
492 printk(KERN_DEBUG "Device: %d Vpi: %d Vci: %d\n",
493 vcc->dev->number,
494 vcc->vpi,
495 vcc->vci);
496 }
497 }
498 }
499 read_unlock(&vcc_sklist_lock);
500 return num_found;
501}
502
503
504static int popen(struct atm_vcc *vcc)
505{
506 struct solos_card *card = vcc->dev->dev_data;
507 struct sk_buff *skb;
508 struct pkt_hdr *header;
509
510 skb = alloc_skb(sizeof(*header), GFP_ATOMIC);
511 if (!skb && net_ratelimit()) {
512 dev_warn(&card->dev->dev, "Failed to allocate sk_buff in popen()\n");
513 return -ENOMEM;
514 }
515 header = (void *)skb_put(skb, sizeof(*header));
516
David Woodhouseb76811a2009-01-27 10:18:51 +1100517 header->size = cpu_to_le16(0);
David Woodhouse9c540042008-12-23 04:09:02 +0000518 header->vpi = cpu_to_le16(vcc->vpi);
519 header->vci = cpu_to_le16(vcc->vci);
520 header->type = cpu_to_le16(PKT_POPEN);
521
522 fpga_queue(card, SOLOS_CHAN(vcc->dev), skb, NULL);
523
524// dev_dbg(&card->dev->dev, "Open for vpi %d and vci %d on interface %d\n", vcc->vpi, vcc->vci, SOLOS_CHAN(vcc->dev));
525 set_bit(ATM_VF_ADDR, &vcc->flags); // accept the vpi / vci
526 set_bit(ATM_VF_READY, &vcc->flags);
527 list_vccs(0);
528
529 if (!opens)
530 iowrite32(1, card->config_regs + IRQ_EN_ADDR);
531
532 opens++; //count open PVCs
533
534 return 0;
535}
536
537static void pclose(struct atm_vcc *vcc)
538{
539 struct solos_card *card = vcc->dev->dev_data;
540 struct sk_buff *skb;
541 struct pkt_hdr *header;
542
543 skb = alloc_skb(sizeof(*header), GFP_ATOMIC);
544 if (!skb) {
545 dev_warn(&card->dev->dev, "Failed to allocate sk_buff in pclose()\n");
546 return;
547 }
548 header = (void *)skb_put(skb, sizeof(*header));
549
David Woodhouseb76811a2009-01-27 10:18:51 +1100550 header->size = cpu_to_le16(0);
David Woodhouse9c540042008-12-23 04:09:02 +0000551 header->vpi = cpu_to_le16(vcc->vpi);
552 header->vci = cpu_to_le16(vcc->vci);
553 header->type = cpu_to_le16(PKT_PCLOSE);
554
555 fpga_queue(card, SOLOS_CHAN(vcc->dev), skb, NULL);
556
557// dev_dbg(&card->dev->dev, "Close for vpi %d and vci %d on interface %d\n", vcc->vpi, vcc->vci, SOLOS_CHAN(vcc->dev));
558 if (!--opens)
559 iowrite32(0, card->config_regs + IRQ_EN_ADDR);
560
561 clear_bit(ATM_VF_ADDR, &vcc->flags);
562 clear_bit(ATM_VF_READY, &vcc->flags);
563
564 return;
565}
566
567static int print_buffer(struct sk_buff *buf)
568{
569 int len,i;
570 char msg[500];
571 char item[10];
572
573 len = buf->len;
574 for (i = 0; i < len; i++){
575 if(i % 8 == 0)
576 sprintf(msg, "%02X: ", i);
577
578 sprintf(item,"%02X ",*(buf->data + i));
579 strcat(msg, item);
580 if(i % 8 == 7) {
581 sprintf(item, "\n");
582 strcat(msg, item);
583 printk(KERN_DEBUG "%s", msg);
584 }
585 }
586 if (i % 8 != 0) {
587 sprintf(item, "\n");
588 strcat(msg, item);
589 printk(KERN_DEBUG "%s", msg);
590 }
591 printk(KERN_DEBUG "\n");
592
593 return 0;
594}
595
596static void fpga_queue(struct solos_card *card, int port, struct sk_buff *skb,
597 struct atm_vcc *vcc)
598{
599 int old_len;
600
601 *(void **)skb->cb = vcc;
602
603 spin_lock(&card->tx_queue_lock);
604 old_len = skb_queue_len(&card->tx_queue[port]);
605 skb_queue_tail(&card->tx_queue[port], skb);
606 spin_unlock(&card->tx_queue_lock);
607
608 /* If TX might need to be started, do so */
609 if (!old_len)
610 fpga_tx(card);
611}
612
613static int fpga_tx(struct solos_card *card)
614{
615 uint32_t tx_pending;
616 uint32_t tx_started = 0;
617 struct sk_buff *skb;
618 struct atm_vcc *vcc;
619 unsigned char port;
620 unsigned long flags;
621
622 spin_lock_irqsave(&card->tx_lock, flags);
623
624 tx_pending = ioread32(card->config_regs + FLAGS_ADDR);
625
626 dev_vdbg(&card->dev->dev, "TX Flags are %X\n", tx_pending);
627
628 for (port = 0; port < card->nr_ports; port++) {
629 if (!(tx_pending & (1 << port))) {
630
631 spin_lock(&card->tx_queue_lock);
632 skb = skb_dequeue(&card->tx_queue[port]);
633 spin_unlock(&card->tx_queue_lock);
634
635 if (!skb)
636 continue;
637
638 if (atmdebug) {
639 dev_info(&card->dev->dev, "Transmitted: port %d\n",
640 port);
641 print_buffer(skb);
642 }
643 memcpy_toio(TX_BUF(card, port), skb->data, skb->len);
644
645 vcc = *(void **)skb->cb;
646
647 if (vcc) {
648 atomic_inc(&vcc->stats->tx);
649 solos_pop(vcc, skb);
650 } else
651 dev_kfree_skb_irq(skb);
652
653 tx_started |= 1 << port; //Set TX full flag
654 }
655 }
656 if (tx_started)
657 iowrite32(tx_started, card->config_regs + FLAGS_ADDR);
658
659 spin_unlock_irqrestore(&card->tx_lock, flags);
660 return 0;
661}
662
663static int psend(struct atm_vcc *vcc, struct sk_buff *skb)
664{
665 struct solos_card *card = vcc->dev->dev_data;
666 struct sk_buff *skb2 = NULL;
667 struct pkt_hdr *header;
David Woodhouseb76811a2009-01-27 10:18:51 +1100668 int pktlen;
David Woodhouse9c540042008-12-23 04:09:02 +0000669
670 //dev_dbg(&card->dev->dev, "psend called.\n");
671 //dev_dbg(&card->dev->dev, "dev,vpi,vci = %d,%d,%d\n",SOLOS_CHAN(vcc->dev),vcc->vpi,vcc->vci);
672
673 if (debug) {
674 skb2 = atm_alloc_charge(vcc, skb->len, GFP_ATOMIC);
675 if (skb2) {
676 memcpy(skb2->data, skb->data, skb->len);
677 skb_put(skb2, skb->len);
678 vcc->push(vcc, skb2);
679 atomic_inc(&vcc->stats->rx);
680 }
681 atomic_inc(&vcc->stats->tx);
682 solos_pop(vcc, skb);
683 return 0;
684 }
685
David Woodhouseb76811a2009-01-27 10:18:51 +1100686 pktlen = skb->len;
687 if (pktlen > (BUF_SIZE - sizeof(*header))) {
David Woodhouse9c540042008-12-23 04:09:02 +0000688 dev_warn(&card->dev->dev, "Length of PDU is too large. Dropping PDU.\n");
689 solos_pop(vcc, skb);
690 return 0;
691 }
692
693 if (!skb_clone_writable(skb, sizeof(*header))) {
694 int expand_by = 0;
695 int ret;
696
697 if (skb_headroom(skb) < sizeof(*header))
698 expand_by = sizeof(*header) - skb_headroom(skb);
699
700 ret = pskb_expand_head(skb, expand_by, 0, GFP_ATOMIC);
701 if (ret) {
Simon Farnsworth4306cad2009-01-19 21:19:29 +0000702 dev_warn(&card->dev->dev, "pskb_expand_head failed.\n");
David Woodhouse9c540042008-12-23 04:09:02 +0000703 solos_pop(vcc, skb);
704 return ret;
705 }
706 }
707
708 header = (void *)skb_push(skb, sizeof(*header));
709
David Woodhouseb76811a2009-01-27 10:18:51 +1100710 /* This does _not_ include the size of the header */
711 header->size = cpu_to_le16(pktlen);
David Woodhouse9c540042008-12-23 04:09:02 +0000712 header->vpi = cpu_to_le16(vcc->vpi);
713 header->vci = cpu_to_le16(vcc->vci);
714 header->type = cpu_to_le16(PKT_DATA);
715
716 fpga_queue(card, SOLOS_CHAN(vcc->dev), skb, vcc);
717
718 return 0;
719}
720
721static struct atmdev_ops fpga_ops = {
722 .open = popen,
723 .close = pclose,
724 .ioctl = NULL,
725 .getsockopt = NULL,
726 .setsockopt = NULL,
727 .send = psend,
728 .send_oam = NULL,
729 .phy_put = NULL,
730 .phy_get = NULL,
731 .change_qos = NULL,
732 .proc_read = NULL,
733 .owner = THIS_MODULE
734};
735
736static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
737{
738 int err, i;
739 uint16_t fpga_ver;
740 uint8_t major_ver, minor_ver;
741 uint32_t data32;
742 struct solos_card *card;
743
744 if (debug)
745 return 0;
746
747 card = kzalloc(sizeof(*card), GFP_KERNEL);
748 if (!card)
749 return -ENOMEM;
750
751 card->dev = dev;
752
753 err = pci_enable_device(dev);
754 if (err) {
755 dev_warn(&dev->dev, "Failed to enable PCI device\n");
756 goto out;
757 }
758
759 err = pci_request_regions(dev, "solos");
760 if (err) {
761 dev_warn(&dev->dev, "Failed to request regions\n");
762 goto out;
763 }
764
765 card->config_regs = pci_iomap(dev, 0, CONFIG_RAM_SIZE);
766 if (!card->config_regs) {
767 dev_warn(&dev->dev, "Failed to ioremap config registers\n");
768 goto out_release_regions;
769 }
770 card->buffers = pci_iomap(dev, 1, DATA_RAM_SIZE);
771 if (!card->buffers) {
772 dev_warn(&dev->dev, "Failed to ioremap data buffers\n");
773 goto out_unmap_config;
774 }
775
776// for(i=0;i<64 ;i+=4){
777// data32=ioread32(card->buffers + i);
778// dev_dbg(&card->dev->dev, "%08lX\n",(unsigned long)data32);
779// }
780
781 //Fill Config Mem with zeros
782 for(i = 0; i < 128; i += 4)
783 iowrite32(0, card->config_regs + i);
784
785 //Set RX empty flags
786 iowrite32(0xF0, card->config_regs + FLAGS_ADDR);
787
788 data32 = ioread32(card->config_regs + FPGA_VER);
789 fpga_ver = (data32 & 0x0000FFFF);
790 major_ver = ((data32 & 0xFF000000) >> 24);
791 minor_ver = ((data32 & 0x00FF0000) >> 16);
792 dev_info(&dev->dev, "Solos FPGA Version %d.%02d svn-%d\n",
793 major_ver, minor_ver, fpga_ver);
794
795 card->nr_ports = 2; /* FIXME: Detect daughterboard */
796
797 err = atm_init(card);
798 if (err)
799 goto out_unmap_both;
800
801 pci_set_drvdata(dev, card);
802 tasklet_init(&card->tlet, solos_bh, (unsigned long)card);
803 spin_lock_init(&card->tx_lock);
804 spin_lock_init(&card->tx_queue_lock);
805 spin_lock_init(&card->cli_queue_lock);
806/*
807 // Set Loopback mode
808 data32 = 0x00010000;
809 iowrite32(data32,card->config_regs + FLAGS_ADDR);
810*/
811/*
812 // Fill Buffers with zeros
813 for (i = 0; i < BUF_SIZE * 8; i += 4)
814 iowrite32(0, card->buffers + i);
815*/
816/*
817 for(i = 0; i < (BUF_SIZE * 1); i += 4)
818 iowrite32(0x12345678, card->buffers + i + (0*BUF_SIZE));
819 for(i = 0; i < (BUF_SIZE * 1); i += 4)
820 iowrite32(0xabcdef98, card->buffers + i + (1*BUF_SIZE));
821
822 // Read Config Memory
823 printk(KERN_DEBUG "Reading Config MEM\n");
824 i = 0;
825 for(i = 0; i < 16; i++) {
826 data32=ioread32(card->buffers + i*(BUF_SIZE/2));
827 printk(KERN_ALERT "Addr: %lX Data: %08lX\n",
828 (unsigned long)(addr_start + i*(BUF_SIZE/2)),
829 (unsigned long)data32);
830 }
831*/
832 //dev_dbg(&card->dev->dev, "Requesting IRQ: %d\n",dev->irq);
833 err = request_irq(dev->irq, solos_irq, IRQF_DISABLED|IRQF_SHARED,
834 "solos-pci", card);
835 if (err)
836 dev_dbg(&card->dev->dev, "Failed to request interrupt IRQ: %d\n", dev->irq);
837
838 // Enable IRQs
839 iowrite32(1, card->config_regs + IRQ_EN_ADDR);
840
Simon Farnsworth7c4015b2009-01-21 20:45:49 +0000841 if(firmware_upgrade != 0){
842 card->flash_chip = 1;
843 flash_upgrade(card);
844 } else {
845 if(fpga_upgrade != 0){
846 card->flash_chip = 0;
847 flash_upgrade(card);
848 }
849 }
David Woodhouse9c540042008-12-23 04:09:02 +0000850 return 0;
851
852 out_unmap_both:
853 pci_iounmap(dev, card->config_regs);
854 out_unmap_config:
855 pci_iounmap(dev, card->buffers);
856 out_release_regions:
857 pci_release_regions(dev);
858 out:
859 return err;
860}
861
862static int atm_init(struct solos_card *card)
863{
864 int i;
865
866 opens = 0;
867
868 for (i = 0; i < card->nr_ports; i++) {
869 skb_queue_head_init(&card->tx_queue[i]);
870 skb_queue_head_init(&card->cli_queue[i]);
871
872 card->atmdev[i] = atm_dev_register("solos-pci", &fpga_ops, -1, NULL);
873 if (!card->atmdev[i]) {
874 dev_err(&card->dev->dev, "Could not register ATM device %d\n", i);
875 atm_remove(card);
876 return -ENODEV;
877 }
878 if (device_create_file(&card->atmdev[i]->class_dev, &dev_attr_console))
879 dev_err(&card->dev->dev, "Could not register console for ATM device %d\n", i);
880
881 dev_info(&card->dev->dev, "Registered ATM device %d\n", card->atmdev[i]->number);
882
883 card->atmdev[i]->ci_range.vpi_bits = 8;
884 card->atmdev[i]->ci_range.vci_bits = 16;
885 card->atmdev[i]->dev_data = card;
886 card->atmdev[i]->phy_data = (void *)(unsigned long)i;
887 }
888 return 0;
889}
890
891static void atm_remove(struct solos_card *card)
892{
893 int i;
894
895 for (i = 0; i < card->nr_ports; i++) {
896 if (card->atmdev[i]) {
897 dev_info(&card->dev->dev, "Unregistering ATM device %d\n", card->atmdev[i]->number);
898 atm_dev_deregister(card->atmdev[i]);
899 }
900 }
901}
902
903static void fpga_remove(struct pci_dev *dev)
904{
905 struct solos_card *card = pci_get_drvdata(dev);
906
907 if (debug)
908 return;
909
910 atm_remove(card);
911
912 dev_vdbg(&dev->dev, "Freeing IRQ\n");
913 // Disable IRQs from FPGA
914 iowrite32(0, card->config_regs + IRQ_EN_ADDR);
915 free_irq(dev->irq, card);
916 tasklet_kill(&card->tlet);
917
918 // iowrite32(0x01,pciregs);
919 dev_vdbg(&dev->dev, "Unmapping PCI resource\n");
920 pci_iounmap(dev, card->buffers);
921 pci_iounmap(dev, card->config_regs);
922
923 dev_vdbg(&dev->dev, "Releasing PCI Region\n");
924 pci_release_regions(dev);
925 pci_disable_device(dev);
926
927 pci_set_drvdata(dev, NULL);
928 kfree(card);
929// dev_dbg(&card->dev->dev, "fpga_remove\n");
930 return;
931}
932
933static struct pci_device_id fpga_pci_tbl[] __devinitdata = {
934 { 0x10ee, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
935 { 0, }
936};
937
938MODULE_DEVICE_TABLE(pci,fpga_pci_tbl);
939
940static struct pci_driver fpga_driver = {
941 .name = "solos",
942 .id_table = fpga_pci_tbl,
943 .probe = fpga_probe,
944 .remove = fpga_remove,
945};
946
947
948static int __init solos_pci_init(void)
949{
950 printk(KERN_INFO "Solos PCI Driver Version %s\n", VERSION);
951 return pci_register_driver(&fpga_driver);
952}
953
954static void __exit solos_pci_exit(void)
955{
956 pci_unregister_driver(&fpga_driver);
957 printk(KERN_INFO "Solos PCI Driver %s Unloaded\n", VERSION);
958}
959
960module_init(solos_pci_init);
961module_exit(solos_pci_exit);