diff options
Diffstat (limited to 'drivers/atm/solos-pci.c')
-rw-r--r-- | drivers/atm/solos-pci.c | 75 |
1 files changed, 66 insertions, 9 deletions
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c index 307321b32cb3..c5f5186d62a3 100644 --- a/drivers/atm/solos-pci.c +++ b/drivers/atm/solos-pci.c | |||
@@ -59,21 +59,29 @@ | |||
59 | #define RX_DMA_ADDR(port) (0x30 + (4 * (port))) | 59 | #define RX_DMA_ADDR(port) (0x30 + (4 * (port))) |
60 | 60 | ||
61 | #define DATA_RAM_SIZE 32768 | 61 | #define DATA_RAM_SIZE 32768 |
62 | #define BUF_SIZE 4096 | 62 | #define BUF_SIZE 2048 |
63 | #define OLD_BUF_SIZE 4096 /* For FPGA versions <= 2*/ | ||
63 | #define FPGA_PAGE 528 /* FPGA flash page size*/ | 64 | #define FPGA_PAGE 528 /* FPGA flash page size*/ |
64 | #define SOLOS_PAGE 512 /* Solos flash page size*/ | 65 | #define SOLOS_PAGE 512 /* Solos flash page size*/ |
65 | #define FPGA_BLOCK (FPGA_PAGE * 8) /* FPGA flash block size*/ | 66 | #define FPGA_BLOCK (FPGA_PAGE * 8) /* FPGA flash block size*/ |
66 | #define SOLOS_BLOCK (SOLOS_PAGE * 8) /* Solos flash block size*/ | 67 | #define SOLOS_BLOCK (SOLOS_PAGE * 8) /* Solos flash block size*/ |
67 | 68 | ||
68 | #define RX_BUF(card, nr) ((card->buffers) + (nr)*BUF_SIZE*2) | 69 | #define RX_BUF(card, nr) ((card->buffers) + (nr)*(card->buffer_size)*2) |
69 | #define TX_BUF(card, nr) ((card->buffers) + (nr)*BUF_SIZE*2 + BUF_SIZE) | 70 | #define TX_BUF(card, nr) ((card->buffers) + (nr)*(card->buffer_size)*2 + (card->buffer_size)) |
71 | #define FLASH_BUF ((card->buffers) + 4*(card->buffer_size)*2) | ||
70 | 72 | ||
71 | #define RX_DMA_SIZE 2048 | 73 | #define RX_DMA_SIZE 2048 |
72 | 74 | ||
75 | #define FPGA_VERSION(a,b) (((a) << 8) + (b)) | ||
76 | #define LEGACY_BUFFERS 2 | ||
77 | #define DMA_SUPPORTED 4 | ||
78 | |||
73 | static int reset = 0; | 79 | static int reset = 0; |
74 | static int atmdebug = 0; | 80 | static int atmdebug = 0; |
75 | static int firmware_upgrade = 0; | 81 | static int firmware_upgrade = 0; |
76 | static int fpga_upgrade = 0; | 82 | static int fpga_upgrade = 0; |
83 | static int db_firmware_upgrade = 0; | ||
84 | static int db_fpga_upgrade = 0; | ||
77 | 85 | ||
78 | struct pkt_hdr { | 86 | struct pkt_hdr { |
79 | __le16 size; | 87 | __le16 size; |
@@ -116,6 +124,8 @@ struct solos_card { | |||
116 | wait_queue_head_t param_wq; | 124 | wait_queue_head_t param_wq; |
117 | wait_queue_head_t fw_wq; | 125 | wait_queue_head_t fw_wq; |
118 | int using_dma; | 126 | int using_dma; |
127 | int fpga_version; | ||
128 | int buffer_size; | ||
119 | }; | 129 | }; |
120 | 130 | ||
121 | 131 | ||
@@ -136,10 +146,14 @@ MODULE_PARM_DESC(reset, "Reset Solos chips on startup"); | |||
136 | MODULE_PARM_DESC(atmdebug, "Print ATM data"); | 146 | MODULE_PARM_DESC(atmdebug, "Print ATM data"); |
137 | MODULE_PARM_DESC(firmware_upgrade, "Initiate Solos firmware upgrade"); | 147 | MODULE_PARM_DESC(firmware_upgrade, "Initiate Solos firmware upgrade"); |
138 | MODULE_PARM_DESC(fpga_upgrade, "Initiate FPGA upgrade"); | 148 | MODULE_PARM_DESC(fpga_upgrade, "Initiate FPGA upgrade"); |
149 | MODULE_PARM_DESC(db_firmware_upgrade, "Initiate daughter board Solos firmware upgrade"); | ||
150 | MODULE_PARM_DESC(db_fpga_upgrade, "Initiate daughter board FPGA upgrade"); | ||
139 | module_param(reset, int, 0444); | 151 | module_param(reset, int, 0444); |
140 | module_param(atmdebug, int, 0644); | 152 | module_param(atmdebug, int, 0644); |
141 | module_param(firmware_upgrade, int, 0444); | 153 | module_param(firmware_upgrade, int, 0444); |
142 | module_param(fpga_upgrade, int, 0444); | 154 | module_param(fpga_upgrade, int, 0444); |
155 | module_param(db_firmware_upgrade, int, 0444); | ||
156 | module_param(db_fpga_upgrade, int, 0444); | ||
143 | 157 | ||
144 | static void fpga_queue(struct solos_card *card, int port, struct sk_buff *skb, | 158 | static void fpga_queue(struct solos_card *card, int port, struct sk_buff *skb, |
145 | struct atm_vcc *vcc); | 159 | struct atm_vcc *vcc); |
@@ -517,10 +531,32 @@ static int flash_upgrade(struct solos_card *card, int chip) | |||
517 | if (chip == 0) { | 531 | if (chip == 0) { |
518 | fw_name = "solos-FPGA.bin"; | 532 | fw_name = "solos-FPGA.bin"; |
519 | blocksize = FPGA_BLOCK; | 533 | blocksize = FPGA_BLOCK; |
520 | } else { | 534 | } |
535 | |||
536 | if (chip == 1) { | ||
521 | fw_name = "solos-Firmware.bin"; | 537 | fw_name = "solos-Firmware.bin"; |
522 | blocksize = SOLOS_BLOCK; | 538 | blocksize = SOLOS_BLOCK; |
523 | } | 539 | } |
540 | |||
541 | if (chip == 2){ | ||
542 | if (card->fpga_version > LEGACY_BUFFERS){ | ||
543 | fw_name = "solos-db-FPGA.bin"; | ||
544 | blocksize = FPGA_BLOCK; | ||
545 | } else { | ||
546 | dev_info(&card->dev->dev, "FPGA version doesn't support daughter board upgrades\n"); | ||
547 | return -EPERM; | ||
548 | } | ||
549 | } | ||
550 | |||
551 | if (chip == 3){ | ||
552 | if (card->fpga_version > LEGACY_BUFFERS){ | ||
553 | fw_name = "solos-Firmware.bin"; | ||
554 | blocksize = SOLOS_BLOCK; | ||
555 | } else { | ||
556 | dev_info(&card->dev->dev, "FPGA version doesn't support daughter board upgrades\n"); | ||
557 | return -EPERM; | ||
558 | } | ||
559 | } | ||
524 | 560 | ||
525 | if (request_firmware(&fw, fw_name, &card->dev->dev)) | 561 | if (request_firmware(&fw, fw_name, &card->dev->dev)) |
526 | return -ENOENT; | 562 | return -ENOENT; |
@@ -536,8 +572,10 @@ static int flash_upgrade(struct solos_card *card, int chip) | |||
536 | data32 = ioread32(card->config_regs + FPGA_MODE); | 572 | data32 = ioread32(card->config_regs + FPGA_MODE); |
537 | 573 | ||
538 | /* Set mode to Chip Erase */ | 574 | /* Set mode to Chip Erase */ |
539 | dev_info(&card->dev->dev, "Set FPGA Flash mode to %s Chip Erase\n", | 575 | if(chip == 0 || chip == 2) |
540 | chip?"Solos":"FPGA"); | 576 | dev_info(&card->dev->dev, "Set FPGA Flash mode to FPGA Chip Erase\n"); |
577 | if(chip == 1 || chip == 3) | ||
578 | dev_info(&card->dev->dev, "Set FPGA Flash mode to Solos Chip Erase\n"); | ||
541 | iowrite32((chip * 2), card->config_regs + FLASH_MODE); | 579 | iowrite32((chip * 2), card->config_regs + FLASH_MODE); |
542 | 580 | ||
543 | 581 | ||
@@ -557,7 +595,10 @@ static int flash_upgrade(struct solos_card *card, int chip) | |||
557 | /* Copy block to buffer, swapping each 16 bits */ | 595 | /* Copy block to buffer, swapping each 16 bits */ |
558 | for(i = 0; i < blocksize; i += 4) { | 596 | for(i = 0; i < blocksize; i += 4) { |
559 | uint32_t word = swahb32p((uint32_t *)(fw->data + offset + i)); | 597 | uint32_t word = swahb32p((uint32_t *)(fw->data + offset + i)); |
560 | iowrite32(word, RX_BUF(card, 3) + i); | 598 | if(card->fpga_version > LEGACY_BUFFERS) |
599 | iowrite32(word, FLASH_BUF + i); | ||
600 | else | ||
601 | iowrite32(word, RX_BUF(card, 3) + i); | ||
561 | } | 602 | } |
562 | 603 | ||
563 | /* Specify block number and then trigger flash write */ | 604 | /* Specify block number and then trigger flash write */ |
@@ -630,6 +671,10 @@ void solos_bh(unsigned long card_arg) | |||
630 | memcpy_fromio(header, RX_BUF(card, port), sizeof(*header)); | 671 | memcpy_fromio(header, RX_BUF(card, port), sizeof(*header)); |
631 | 672 | ||
632 | size = le16_to_cpu(header->size); | 673 | size = le16_to_cpu(header->size); |
674 | if (size > (card->buffer_size - sizeof(*header))){ | ||
675 | dev_warn(&card->dev->dev, "Invalid buffer size\n"); | ||
676 | continue; | ||
677 | } | ||
633 | 678 | ||
634 | skb = alloc_skb(size + 1, GFP_ATOMIC); | 679 | skb = alloc_skb(size + 1, GFP_ATOMIC); |
635 | if (!skb) { | 680 | if (!skb) { |
@@ -1094,12 +1139,18 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
1094 | fpga_ver = (data32 & 0x0000FFFF); | 1139 | fpga_ver = (data32 & 0x0000FFFF); |
1095 | major_ver = ((data32 & 0xFF000000) >> 24); | 1140 | major_ver = ((data32 & 0xFF000000) >> 24); |
1096 | minor_ver = ((data32 & 0x00FF0000) >> 16); | 1141 | minor_ver = ((data32 & 0x00FF0000) >> 16); |
1142 | card->fpga_version = FPGA_VERSION(major_ver,minor_ver); | ||
1143 | if (card->fpga_version > LEGACY_BUFFERS) | ||
1144 | card->buffer_size = BUF_SIZE; | ||
1145 | else | ||
1146 | card->buffer_size = OLD_BUF_SIZE; | ||
1097 | dev_info(&dev->dev, "Solos FPGA Version %d.%02d svn-%d\n", | 1147 | dev_info(&dev->dev, "Solos FPGA Version %d.%02d svn-%d\n", |
1098 | major_ver, minor_ver, fpga_ver); | 1148 | major_ver, minor_ver, fpga_ver); |
1099 | 1149 | ||
1100 | if (0 && fpga_ver > 27) | 1150 | if (card->fpga_version >= DMA_SUPPORTED){ |
1101 | card->using_dma = 1; | 1151 | card->using_dma = 1; |
1102 | else { | 1152 | } else { |
1153 | card->using_dma = 0; | ||
1103 | /* Set RX empty flag for all ports */ | 1154 | /* Set RX empty flag for all ports */ |
1104 | iowrite32(0xF0, card->config_regs + FLAGS_ADDR); | 1155 | iowrite32(0xF0, card->config_regs + FLAGS_ADDR); |
1105 | } | 1156 | } |
@@ -1131,6 +1182,12 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
1131 | if (firmware_upgrade) | 1182 | if (firmware_upgrade) |
1132 | flash_upgrade(card, 1); | 1183 | flash_upgrade(card, 1); |
1133 | 1184 | ||
1185 | if (db_fpga_upgrade) | ||
1186 | flash_upgrade(card, 2); | ||
1187 | |||
1188 | if (db_firmware_upgrade) | ||
1189 | flash_upgrade(card, 3); | ||
1190 | |||
1134 | err = atm_init(card); | 1191 | err = atm_init(card); |
1135 | if (err) | 1192 | if (err) |
1136 | goto out_free_irq; | 1193 | goto out_free_irq; |