aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDavid Woodhouse <David.Woodhouse@intel.com>2012-12-19 06:01:21 -0500
committerDavid S. Miller <davem@davemloft.net>2012-12-19 17:53:53 -0500
commit152a2a8b5e1d4cbe91a7c66f1028db15164a3766 (patch)
tree2a3cc4287755749cc5e4e6a7fe837ab69b6a5703 /drivers
parent13af816469db3449c072afbae6c4c1bd9ccecccb (diff)
solos-pci: ensure all TX packets are aligned to 4 bytes
The FPGA can't handled unaligned DMA (yet). So copy into an aligned buffer, if skb->data isn't suitably aligned. Signed-off-by: David Woodhouse <David.Woodhouse@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/atm/solos-pci.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c
index aa4f35d52a92..d70abe77f737 100644
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -128,9 +128,11 @@ struct solos_card {
128 struct sk_buff_head cli_queue[4]; 128 struct sk_buff_head cli_queue[4];
129 struct sk_buff *tx_skb[4]; 129 struct sk_buff *tx_skb[4];
130 struct sk_buff *rx_skb[4]; 130 struct sk_buff *rx_skb[4];
131 unsigned char *dma_bounce;
131 wait_queue_head_t param_wq; 132 wait_queue_head_t param_wq;
132 wait_queue_head_t fw_wq; 133 wait_queue_head_t fw_wq;
133 int using_dma; 134 int using_dma;
135 int dma_alignment;
134 int fpga_version; 136 int fpga_version;
135 int buffer_size; 137 int buffer_size;
136 int atmel_flash; 138 int atmel_flash;
@@ -1083,7 +1085,12 @@ static uint32_t fpga_tx(struct solos_card *card)
1083 tx_started |= 1 << port; 1085 tx_started |= 1 << port;
1084 oldskb = skb; /* We're done with this skb already */ 1086 oldskb = skb; /* We're done with this skb already */
1085 } else if (skb && card->using_dma) { 1087 } else if (skb && card->using_dma) {
1086 SKB_CB(skb)->dma_addr = pci_map_single(card->dev, skb->data, 1088 unsigned char *data = skb->data;
1089 if ((unsigned long)data & card->dma_alignment) {
1090 data = card->dma_bounce + (BUF_SIZE * port);
1091 memcpy(data, skb->data, skb->len);
1092 }
1093 SKB_CB(skb)->dma_addr = pci_map_single(card->dev, data,
1087 skb->len, PCI_DMA_TODEVICE); 1094 skb->len, PCI_DMA_TODEVICE);
1088 card->tx_skb[port] = skb; 1095 card->tx_skb[port] = skb;
1089 iowrite32(SKB_CB(skb)->dma_addr, 1096 iowrite32(SKB_CB(skb)->dma_addr,
@@ -1261,18 +1268,27 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
1261 else 1268 else
1262 card->atmel_flash = 0; 1269 card->atmel_flash = 0;
1263 1270
1271 data32 = ioread32(card->config_regs + PORTS);
1272 card->nr_ports = (data32 & 0x000000FF);
1273
1264 if (card->fpga_version >= DMA_SUPPORTED) { 1274 if (card->fpga_version >= DMA_SUPPORTED) {
1265 pci_set_master(dev); 1275 pci_set_master(dev);
1266 card->using_dma = 1; 1276 card->using_dma = 1;
1277 if (1) { /* All known FPGA versions so far */
1278 card->dma_alignment = 3;
1279 card->dma_bounce = kmalloc(card->nr_ports * BUF_SIZE, GFP_KERNEL);
1280 if (!card->dma_bounce) {
1281 dev_warn(&card->dev->dev, "Failed to allocate DMA bounce buffers\n");
1282 /* Fallback to MMIO doesn't work */
1283 goto out_unmap_both;
1284 }
1285 }
1267 } else { 1286 } else {
1268 card->using_dma = 0; 1287 card->using_dma = 0;
1269 /* Set RX empty flag for all ports */ 1288 /* Set RX empty flag for all ports */
1270 iowrite32(0xF0, card->config_regs + FLAGS_ADDR); 1289 iowrite32(0xF0, card->config_regs + FLAGS_ADDR);
1271 } 1290 }
1272 1291
1273 data32 = ioread32(card->config_regs + PORTS);
1274 card->nr_ports = (data32 & 0x000000FF);
1275
1276 pci_set_drvdata(dev, card); 1292 pci_set_drvdata(dev, card);
1277 1293
1278 tasklet_init(&card->tlet, solos_bh, (unsigned long)card); 1294 tasklet_init(&card->tlet, solos_bh, (unsigned long)card);
@@ -1319,6 +1335,7 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
1319 tasklet_kill(&card->tlet); 1335 tasklet_kill(&card->tlet);
1320 1336
1321 out_unmap_both: 1337 out_unmap_both:
1338 kfree(card->dma_bounce);
1322 pci_set_drvdata(dev, NULL); 1339 pci_set_drvdata(dev, NULL);
1323 pci_iounmap(dev, card->buffers); 1340 pci_iounmap(dev, card->buffers);
1324 out_unmap_config: 1341 out_unmap_config:
@@ -1429,6 +1446,8 @@ static void fpga_remove(struct pci_dev *dev)
1429 free_irq(dev->irq, card); 1446 free_irq(dev->irq, card);
1430 tasklet_kill(&card->tlet); 1447 tasklet_kill(&card->tlet);
1431 1448
1449 kfree(card->dma_bounce);
1450
1432 /* Release device from reset */ 1451 /* Release device from reset */
1433 iowrite32(0, card->config_regs + FPGA_MODE); 1452 iowrite32(0, card->config_regs + FPGA_MODE);
1434 (void)ioread32(card->config_regs + FPGA_MODE); 1453 (void)ioread32(card->config_regs + FPGA_MODE);