Commit a76bff21 authored by Jaco Hofmann's avatar Jaco Hofmann

Backports driver improvements

parent a543f07d
...@@ -72,15 +72,15 @@ void blue_dma_transmit_from_device(void * device_buffer, dma_addr_t host_handle, ...@@ -72,15 +72,15 @@ void blue_dma_transmit_from_device(void * device_buffer, dma_addr_t host_handle,
// fflink_warn("got killed while aquiring the mutex\n"); // fflink_warn("got killed while aquiring the mutex\n");
/* SA */ /* SA */
pcie_writel((unsigned long)device_buffer, device_base_addr + REG_FPGA_ADDR); pcie_writeq((unsigned long)device_buffer, device_base_addr + REG_FPGA_ADDR);
/* DA */ /* DA */
pcie_writel(host_handle, device_base_addr + REG_HOST_ADDR); pcie_writeq(host_handle, device_base_addr + REG_HOST_ADDR);
/* btt */ /* btt */
pcie_writel(btt, device_base_addr + REG_BTT); pcie_writeq(btt, device_base_addr + REG_BTT);
/* presvious data have to be written first */ /* presvious data have to be written first */
wmb(); wmb();
/* start cmd */ /* start cmd */
pcie_writel(CMD_READ, device_base_addr + REG_CMD); pcie_writeq(CMD_READ, device_base_addr + REG_CMD);
//mutex_unlock(&dma_regs_mutex); //mutex_unlock(&dma_regs_mutex);
} }
...@@ -100,15 +100,15 @@ void blue_dma_transmit_to_device(void * device_buffer, dma_addr_t host_handle, i ...@@ -100,15 +100,15 @@ void blue_dma_transmit_to_device(void * device_buffer, dma_addr_t host_handle, i
// fflink_warn("got killed while aquiring the mutex\n"); // fflink_warn("got killed while aquiring the mutex\n");
/* SA */ /* SA */
pcie_writel(host_handle, device_base_addr + REG_HOST_ADDR); pcie_writeq(host_handle, device_base_addr + REG_HOST_ADDR);
/* DA */ /* DA */
pcie_writel((unsigned long)device_buffer, device_base_addr + REG_FPGA_ADDR); pcie_writeq((unsigned long)device_buffer, device_base_addr + REG_FPGA_ADDR);
/* btt */ /* btt */
pcie_writel(btt, device_base_addr + REG_BTT); pcie_writeq(btt, device_base_addr + REG_BTT);
/* presvious data have to be written first */ /* presvious data have to be written first */
wmb(); wmb();
/* start cmd */ /* start cmd */
pcie_writel(CMD_WRITE, device_base_addr + REG_CMD); pcie_writeq(CMD_WRITE, device_base_addr + REG_CMD);
//mutex_unlock(&dma_regs_mutex); //mutex_unlock(&dma_regs_mutex);
} }
......
...@@ -111,26 +111,27 @@ static int user_close(struct inode *inode, struct file *filp) ...@@ -111,26 +111,27 @@ static int user_close(struct inode *inode, struct file *filp)
static ssize_t user_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) static ssize_t user_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{ {
struct user_rw_params params; struct user_rw_params params;
uint32_t i, err = 0, static_buffer[STATIC_BUFFER_SIZE], *copy_buffer; uint32_t i, err = 0;
uint32_t static_buffer[STATIC_BUFFER_SIZE], *copy_buffer;
bool use_dynamic = false; bool use_dynamic = false;
fflink_notice("Called for device minor %d\n", ((struct priv_data_struct *) filp->private_data)->minor); fflink_notice("Called for device minor %d\n", ((struct priv_data_struct *) filp->private_data)->minor);
copy_buffer = static_buffer; copy_buffer = static_buffer;
if(count != sizeof(struct user_rw_params)) { if (count != sizeof(struct user_rw_params)) {
fflink_warn("Wrong size to parse parameters accordingly %ld vs %ld\n", count, sizeof(struct user_rw_params)); fflink_warn("Wrong size to parse parameters accordingly %ld vs %ld\n", count, sizeof(struct user_rw_params));
return -EACCES; return -EACCES;
} }
if(copy_from_user(&params, buf, count)) { if (copy_from_user(&params, buf, count)) {
fflink_warn("Couldn't copy all bytes from user-space to parse parameters\n"); fflink_warn("Couldn't copy all bytes from user-space to parse parameters\n");
return -EACCES; return -EACCES;
} }
if(params.btt > STATIC_BUFFER_SIZE*REGISTER_BYTE_SIZE) { if (params.btt > STATIC_BUFFER_SIZE * REGISTER_BYTE_SIZE) {
fflink_info("Allocating %d bytes dynamically - only %d available statically\n", params.btt, STATIC_BUFFER_SIZE*REGISTER_BYTE_SIZE); fflink_info("Allocating %d bytes dynamically - only %d available statically\n", params.btt, STATIC_BUFFER_SIZE * REGISTER_BYTE_SIZE);
copy_buffer = kmalloc(params.btt, GFP_KERNEL); copy_buffer = kmalloc(params.btt, GFP_KERNEL);
if(!copy_buffer) { if (!copy_buffer) {
fflink_warn("Couldn't allocate dynamic buffer for transfer\n"); fflink_warn("Couldn't allocate dynamic buffer for transfer\n");
return -EACCES; return -EACCES;
} }
...@@ -139,15 +140,23 @@ static ssize_t user_read(struct file *filp, char __user *buf, size_t count, loff ...@@ -139,15 +140,23 @@ static ssize_t user_read(struct file *filp, char __user *buf, size_t count, loff
} }
fflink_info("Copy %d bytes from address %llX to address %llX\n", params.btt, params.fpga_addr, params.host_addr); fflink_info("Copy %d bytes from address %llX to address %llX\n", params.btt, params.fpga_addr, params.host_addr);
for(i = 0; i < params.btt/4; i++)
copy_buffer[i] = pcie_readl((void*) (params.fpga_addr + i*4));
if(copy_to_user((void *)params.host_addr, copy_buffer, params.btt)) { if (params.btt == 4) {
copy_buffer[0] = pcie_readl((void*) params.fpga_addr);
}
else if (params.btt == 8) {
((uint64_t*)copy_buffer)[0] = pcie_readq((void*) params.fpga_addr);
} else {
for (i = 0; i < params.btt / 4; i++)
copy_buffer[i] = pcie_readl((void*) (params.fpga_addr + i * 4));
}
if (copy_to_user((void *)params.host_addr, copy_buffer, params.btt)) {
fflink_warn("Couldn't copy all bytes to user-space\n"); fflink_warn("Couldn't copy all bytes to user-space\n");
err = -EACCES; err = -EACCES;
} }
if(unlikely(use_dynamic)) { if (unlikely(use_dynamic)) {
fflink_info("Freeing dynamic buffer\n"); fflink_info("Freeing dynamic buffer\n");
kfree(copy_buffer); kfree(copy_buffer);
} }
...@@ -173,20 +182,20 @@ static ssize_t user_write(struct file *filp, const char __user *buf, size_t coun ...@@ -173,20 +182,20 @@ static ssize_t user_write(struct file *filp, const char __user *buf, size_t coun
copy_buffer = static_buffer; copy_buffer = static_buffer;
if(count != sizeof(struct user_rw_params)) { if (count != sizeof(struct user_rw_params)) {
fflink_warn("Wrong size to parse parameters accordingly %ld vs %ld\n", count, sizeof(struct user_rw_params)); fflink_warn("Wrong size to parse parameters accordingly %ld vs %ld\n", count, sizeof(struct user_rw_params));
return -EACCES; return -EACCES;
} }
if(copy_from_user(&params, buf, count)) { if (copy_from_user(&params, buf, count)) {
fflink_warn("Couldn't copy all bytes from user-space to parse parameters\n"); fflink_warn("Couldn't copy all bytes from user-space to parse parameters\n");
return -EACCES; return -EACCES;
} }
if(params.btt > STATIC_BUFFER_SIZE*REGISTER_BYTE_SIZE) { if (params.btt > STATIC_BUFFER_SIZE * REGISTER_BYTE_SIZE) {
fflink_info("Allocating %d bytes dynamically - only %d available statically\n", params.btt, STATIC_BUFFER_SIZE*REGISTER_BYTE_SIZE); fflink_info("Allocating %d bytes dynamically - only %d available statically\n", params.btt, STATIC_BUFFER_SIZE * REGISTER_BYTE_SIZE);
copy_buffer = kmalloc(params.btt, GFP_KERNEL); copy_buffer = kmalloc(params.btt, GFP_KERNEL);
if(!copy_buffer) { if (!copy_buffer) {
fflink_warn("Couldn't allocate dynamic buffer for transfer\n"); fflink_warn("Couldn't allocate dynamic buffer for transfer\n");
return -EACCES; return -EACCES;
} }
...@@ -194,18 +203,25 @@ static ssize_t user_write(struct file *filp, const char __user *buf, size_t coun ...@@ -194,18 +203,25 @@ static ssize_t user_write(struct file *filp, const char __user *buf, size_t coun
use_dynamic = true; use_dynamic = true;
} }
if(copy_from_user(copy_buffer, (void*)params.host_addr, params.btt)) { if (copy_from_user(copy_buffer, (void*)params.host_addr, params.btt)) {
fflink_warn("Couldn't copy all bytes from user-space\n"); fflink_warn("Couldn't copy all bytes from user-space\n");
err = -EACCES; err = -EACCES;
goto USER_WRITE_CLEANUP; goto USER_WRITE_CLEANUP;
} }
fflink_info("Copy %d bytes to address %llX from address %llX\n", params.btt, params.fpga_addr, params.host_addr); fflink_info("Copy %d bytes to address %llX from address %llX\n", params.btt, params.fpga_addr, params.host_addr);
for(i = 0; i < params.btt/4; i++) if (params.btt == 4) {
pcie_writel(copy_buffer[i], (void*) (params.fpga_addr + i*4)); pcie_writel(copy_buffer[0], (void*) params.fpga_addr);
}
else if (params.btt == 8) {
pcie_writeq(((uint64_t*)copy_buffer)[0], (void*) params.fpga_addr);
} else {
for (i = 0; i < params.btt / 4; i++)
pcie_writel(copy_buffer[i], (void*) (params.fpga_addr + i * 4));
}
USER_WRITE_CLEANUP: USER_WRITE_CLEANUP:
if(unlikely(use_dynamic)) { if (unlikely(use_dynamic)) {
fflink_info("Freeing dynamic buffer\n"); fflink_info("Freeing dynamic buffer\n");
kfree(copy_buffer); kfree(copy_buffer);
} }
...@@ -232,33 +248,33 @@ static long user_ioctl(struct file *filp, unsigned int ioctl_num, unsigned long ...@@ -232,33 +248,33 @@ static long user_ioctl(struct file *filp, unsigned int ioctl_num, unsigned long
struct user_ioctl_params params; struct user_ioctl_params params;
fflink_notice("Called for device minor %d\n", p->minor); fflink_notice("Called for device minor %d\n", p->minor);
if(_IOC_SIZE(ioctl_num) != sizeof(struct user_ioctl_params)) { if (_IOC_SIZE(ioctl_num) != sizeof(struct user_ioctl_params)) {
fflink_warn("Wrong size to read out registers %d vs %ld\n", _IOC_SIZE(ioctl_num), sizeof(struct user_ioctl_params)); fflink_warn("Wrong size to read out registers %d vs %ld\n", _IOC_SIZE(ioctl_num), sizeof(struct user_ioctl_params));
return -EACCES; return -EACCES;
} }
if(copy_from_user(&params, (void *)ioctl_param, _IOC_SIZE(ioctl_num))) { if (copy_from_user(&params, (void *)ioctl_param, _IOC_SIZE(ioctl_num))) {
fflink_warn("Couldn't copy all bytes\n"); fflink_warn("Couldn't copy all bytes\n");
return -EACCES; return -EACCES;
} }
switch(ioctl_num) { switch (ioctl_num) {
case IOCTL_CMD_USER_WAIT_EVENT: case IOCTL_CMD_USER_WAIT_EVENT:
fflink_info("IOCTL_CMD_USER_WAIT_EVENT with Param-Size: %d byte\n", _IOC_SIZE(ioctl_num)); fflink_info("IOCTL_CMD_USER_WAIT_EVENT with Param-Size: %d byte\n", _IOC_SIZE(ioctl_num));
fflink_info("Want to write %X to address %llX with event %d\n", params.data, params.fpga_addr, params.event); fflink_info("Want to write %X to address %llX with event %d\n", params.data, params.fpga_addr, params.event);
irq_counter = priv_data.user_condition[params.event];
pcie_writel(params.data, (void*) params.fpga_addr); irq_counter = priv_data.user_condition[params.event];
if(wait_event_interruptible(p->user_wait_queue[params.event], (irq_counter != p->user_condition[params.event]))) { pcie_writel(params.data, (void*) params.fpga_addr);
fflink_warn("got killed while hanging in waiting queue\n");
break;
}
if (wait_event_interruptible(p->user_wait_queue[params.event], (irq_counter != p->user_condition[params.event]))) {
fflink_warn("got killed while hanging in waiting queue\n");
break; break;
default: }
fflink_warn("default case - nothing to do here\n");
break; break;
default:
fflink_warn("default case - nothing to do here\n");
break;
} }
return 0; return 0;
...@@ -296,7 +312,7 @@ static int user_mmap(struct file *filp, struct vm_area_struct *vma) ...@@ -296,7 +312,7 @@ static int user_mmap(struct file *filp, struct vm_area_struct *vma)
irqreturn_t intr_handler_user(int irq, void * dev_id) irqreturn_t intr_handler_user(int irq, void * dev_id)
{ {
int irq_translated = pcie_translate_irq_number(irq) - 4; int irq_translated = pcie_translate_irq_number(irq) - 4;
if(irq_translated != -1) { if (irq_translated != -1) {
fflink_info("User interrupt for IRQ %d called with irq %d\n", irq_translated, irq); fflink_info("User interrupt for IRQ %d called with irq %d\n", irq_translated, irq);
priv_data.user_condition[irq_translated] += 1; priv_data.user_condition[irq_translated] += 1;
wake_up_interruptible_sync(&priv_data.user_wait_queue[irq_translated]); wake_up_interruptible_sync(&priv_data.user_wait_queue[irq_translated]);
...@@ -345,9 +361,9 @@ int char_user_register(void) ...@@ -345,9 +361,9 @@ int char_user_register(void)
goto error_add_to_system; goto error_add_to_system;
} }
for(i = 0; i < FFLINK_USER_NODES; i++) { for (i = 0; i < FFLINK_USER_NODES; i++) {
/* create device file via udev */ /* create device file via udev */
device = device_create(char_user_class, NULL, MKDEV(MAJOR(char_user_dev_t), MINOR(char_user_dev_t)+i), NULL, FFLINK_USER_NAME "_%d", MINOR(char_user_dev_t)+i); device = device_create(char_user_class, NULL, MKDEV(MAJOR(char_user_dev_t), MINOR(char_user_dev_t) + i), NULL, FFLINK_USER_NAME "_%d", MINOR(char_user_dev_t) + i);
if (IS_ERR(device)) { if (IS_ERR(device)) {
err = PTR_ERR(device); err = PTR_ERR(device);
fflink_warn("failed while device create %d\n", MINOR(char_user_dev_t)); fflink_warn("failed while device create %d\n", MINOR(char_user_dev_t));
...@@ -359,13 +375,13 @@ int char_user_register(void) ...@@ -359,13 +375,13 @@ int char_user_register(void)
/* check if ID core is readable */ /* check if ID core is readable */
hw_id = pcie_readl((void*) HW_ID_ADDR); hw_id = pcie_readl((void*) HW_ID_ADDR);
if(hw_id != HW_ID_MAGIC) { if (hw_id != HW_ID_MAGIC) {
fflink_warn("ID Core not found (was %X - should: %X)\n", hw_id, HW_ID_MAGIC); fflink_warn("ID Core not found (was %X - should: %X)\n", hw_id, HW_ID_MAGIC);
return -ENOTEMPTY; goto error_device_create;
} }
/* init control structures for synchron sys-calls */ /* init control structures for synchron sys-calls */
for(i = 0; i < PE_IRQS; ++i) { for (i = 0; i < PE_IRQS; ++i) {
init_waitqueue_head(&priv_data.user_wait_queue[i]); init_waitqueue_head(&priv_data.user_wait_queue[i]);
priv_data.user_condition[i] = 0; priv_data.user_condition[i] = 0;
} }
...@@ -374,8 +390,8 @@ int char_user_register(void) ...@@ -374,8 +390,8 @@ int char_user_register(void)
/* tidy up for everything successfully allocated */ /* tidy up for everything successfully allocated */
error_device_create: error_device_create:
for(i = i - 1; i >= 0; i--) { for (i = i - 1; i >= 0; i--) {
device_destroy(char_user_class, MKDEV(MAJOR(char_user_dev_t), MINOR(char_user_dev_t)+i)); device_destroy(char_user_class, MKDEV(MAJOR(char_user_dev_t), MINOR(char_user_dev_t) + i));
} }
cdev_del(&char_user_cdev); cdev_del(&char_user_cdev);
error_add_to_system: error_add_to_system:
...@@ -397,8 +413,8 @@ void char_user_unregister(void) ...@@ -397,8 +413,8 @@ void char_user_unregister(void)
fflink_info("Tidy up\n"); fflink_info("Tidy up\n");
for(i = 0; i < FFLINK_USER_NODES; i++) { for (i = 0; i < FFLINK_USER_NODES; i++) {
device_destroy(char_user_class, MKDEV(MAJOR(char_user_dev_t), MINOR(char_user_dev_t)+i)); device_destroy(char_user_class, MKDEV(MAJOR(char_user_dev_t), MINOR(char_user_dev_t) + i));
} }
cdev_del(&char_user_cdev); cdev_del(&char_user_cdev);
......
...@@ -41,7 +41,9 @@ struct pci_dev* get_pcie_dev(void); ...@@ -41,7 +41,9 @@ struct pci_dev* get_pcie_dev(void);
/* wrapper to read/write from pcie-bar0 */ /* wrapper to read/write from pcie-bar0 */
void pcie_writel(unsigned long data, void * addr); void pcie_writel(unsigned long data, void * addr);
void pcie_writeq(unsigned long long data, void * addr);
unsigned long pcie_readl(void * addr); unsigned long pcie_readl(void * addr);
unsigned long long pcie_readq(void * addr);
void pcie_writel_bar2(unsigned long data, void * addr); void pcie_writel_bar2(unsigned long data, void * addr);
unsigned long pcie_readl_bar2(void * addr); unsigned long pcie_readl_bar2(void * addr);
......
...@@ -66,9 +66,14 @@ static const fflink_dma_t fflink_dma[] = { ...@@ -66,9 +66,14 @@ static const fflink_dma_t fflink_dma[] = {
void dma_ctrl_init(void * device_base_addr) void dma_ctrl_init(void * device_base_addr)
{ {
if(pcie_readl(device_base_addr + REG_ID) == 0xE5A0023) {
uint64_t id = pcie_readq(device_base_addr + REG_ID);
if ((id & 0xFFFFFFFF) == 0xE5A0023) {
dma_used = DMA_USED_BLUE; dma_used = DMA_USED_BLUE;
fflink_warn("Detected BlueDMA\n"); fflink_warn("Detected BlueDMA\n");
fflink_warn("PCIE Beats per Burst: %u\n", (uint8_t)(id >> 32));
fflink_warn("FPGA Beats per Burst: %u\n", (uint8_t)(id >> 40));
fflink_warn("Smallest alignment: %u\n", (uint8_t)(id >> 48));
} else { } else {
dma_used = DMA_USED_DUAL; dma_used = DMA_USED_DUAL;
fflink_warn("Detected DualDMA\n"); fflink_warn("Detected DualDMA\n");
......
...@@ -79,7 +79,8 @@ void dual_dma_transmit_from_device(void * device_buffer, dma_addr_t host_handle, ...@@ -79,7 +79,8 @@ void dual_dma_transmit_from_device(void * device_buffer, dma_addr_t host_handle,
/* SA */ /* SA */
pcie_writel((unsigned long) device_buffer, device_base_addr + REG_FPGA_ADDR_LOW); pcie_writel((unsigned long) device_buffer, device_base_addr + REG_FPGA_ADDR_LOW);
/* DA */ /* DA */
pcie_writel(host_handle, device_base_addr + REG_HOST_ADDR_LOW); pcie_writel((uint32_t)host_handle, device_base_addr + REG_HOST_ADDR_LOW);
pcie_writel((uint32_t) (host_handle >> 32), device_base_addr + REG_HOST_ADDR_HIGH);
/* btt */ /* btt */
pcie_writel(btt, device_base_addr + REG_BTT); pcie_writel(btt, device_base_addr + REG_BTT);
/* presvious data have to be written first */ /* presvious data have to be written first */
...@@ -105,7 +106,8 @@ void dual_dma_transmit_to_device(void * device_buffer, dma_addr_t host_handle, i ...@@ -105,7 +106,8 @@ void dual_dma_transmit_to_device(void * device_buffer, dma_addr_t host_handle, i
// fflink_warn("got killed while aquiring the mutex\n"); // fflink_warn("got killed while aquiring the mutex\n");
/* SA */ /* SA */
pcie_writel(host_handle, device_base_addr + REG_HOST_ADDR_LOW); pcie_writel((uint32_t)host_handle, device_base_addr + REG_HOST_ADDR_LOW);
pcie_writel((uint32_t) (host_handle >> 32), device_base_addr + REG_HOST_ADDR_HIGH);
/* DA */ /* DA */
pcie_writel((unsigned long) device_buffer, device_base_addr + REG_FPGA_ADDR_LOW); pcie_writel((unsigned long) device_buffer, device_base_addr + REG_FPGA_ADDR_LOW);
/* btt */ /* btt */
......
...@@ -46,7 +46,7 @@ static int claim_device(struct pci_dev *pdev) ...@@ -46,7 +46,7 @@ static int claim_device(struct pci_dev *pdev)
/* wake up the pci device */ /* wake up the pci device */
err = pci_enable_device(pdev); err = pci_enable_device(pdev);
if(err) { if (err) {
fflink_warn("failed to enable pci device %d\n", err); fflink_warn("failed to enable pci device %d\n", err);
goto error_pci_en; goto error_pci_en;
} }
...@@ -95,22 +95,9 @@ error_pci_en: ...@@ -95,22 +95,9 @@ error_pci_en:
* */ * */
static int configure_device(struct pci_dev *pdev) static int configure_device(struct pci_dev *pdev)
{ {
//int err = 0;
u16 ctrl_reg = 0;
fflink_warn("Trying to find optimal MPS and ReadRQ Settings\n");
pcie_set_mps(pdev, 256);
pcie_set_readrq(pdev, 256);
fflink_warn("Settings of MPS: %d and Maximum Read Request %d\n", pcie_get_mps(pdev), pcie_get_readrq(pdev)); fflink_warn("Settings of MPS: %d and Maximum Read Request %d\n", pcie_get_mps(pdev), pcie_get_readrq(pdev));
/* set RCB to maximum */
pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &ctrl_reg);
fflink_info("Settings of PCI_EXP_LNKCTL from pcie-device: %X\n", ctrl_reg);
pcie_capability_write_word(pdev, PCI_EXP_LNKCTL, ctrl_reg | PCI_EXP_LNKCTL_RCB);
return 0; return 0;
} }
/** /**
* @brief Register specific function with msi interrupt line * @brief Register specific function with msi interrupt line
* @param pdev Pointer to pci-device, which should be allocated * @param pdev Pointer to pci-device, which should be allocated
...@@ -122,19 +109,22 @@ static int register_intr_handler(struct pci_dev *pdev, int c) ...@@ -122,19 +109,22 @@ static int register_intr_handler(struct pci_dev *pdev, int c)
int err = -1; int err = -1;
/* Request interrupt line for unique function /* Request interrupt line for unique function
* alternatively function will be called from free_irq as well with flag IRQF_SHARED */ * alternatively function will be called from free_irq as well with flag IRQF_SHARED */
if(c >= 0 && c < 4) { if (c == 0) {
err = request_irq(pci_irq_vector(pdev,c), intr_handler_dma, IRQF_EARLY_RESUME, FFLINK_PCI_NAME, pdev);
err = request_irq(pci_irq_vector(pdev, c), intr_handler_dma, IRQF_EARLY_RESUME, FFLINK_PCI_NAME, pdev);
} }
if(c >= 4) { if (c == 1 || c == 2 || c == 3) err = -2;
err = request_irq(pci_irq_vector(pdev,c), intr_handler_user, IRQF_EARLY_RESUME, FFLINK_PCI_NAME, pdev);
if (c >= 4) {
err = request_irq(pci_irq_vector(pdev, c), intr_handler_user, IRQF_EARLY_RESUME, FFLINK_PCI_NAME, pdev);
} }
// Save the c to irq mapping for later use // Save the c to irq mapping for later use
if(!err) { if (!err) {
pci_data.irq_mapping[c] = pci_irq_vector(pdev,c); pci_data.irq_mapping[c] = pci_irq_vector(pdev, c);
fflink_notice("Created mapping between interrupt %d and %d", c, pci_data.irq_mapping[c]); fflink_notice("Created mapping between interrupt %d and %d", c, pci_data.irq_mapping[c]);
fflink_notice("Interrupt Line %d/%d assigned with return value %d\n", c, pci_irq_vector(pdev,c), err); fflink_notice("Interrupt Line %d/%d assigned with return value %d\n", c, pci_irq_vector(pdev, c), err);
} }
return err; return err;
} }
...@@ -143,8 +133,8 @@ static int free_irqs(struct pci_dev *pdev) ...@@ -143,8 +133,8 @@ static int free_irqs(struct pci_dev *pdev)
{ {
int i; int i;
for(i = 0; i < REQUIRED_INTERRUPTS; i++) { for (i = 0; i < REQUIRED_INTERRUPTS; i++) {
if(pci_data.irq_mapping[i] != -1) { if (pci_data.irq_mapping[i] != -1) {
fflink_notice("Freeing interrupt %d with mapping %d", i, pci_data.irq_mapping[i]); fflink_notice("Freeing interrupt %d with mapping %d", i, pci_data.irq_mapping[i]);
free_irq(pci_data.irq_mapping[i], pdev); free_irq(pci_data.irq_mapping[i], pdev);
pci_data.irq_mapping[i] = -1; pci_data.irq_mapping[i] = -1;
...@@ -155,8 +145,8 @@ static int free_irqs(struct pci_dev *pdev) ...@@ -155,8 +145,8 @@ static int free_irqs(struct pci_dev *pdev)
int pcie_translate_irq_number(int irq) { int pcie_translate_irq_number(int irq) {
int i; int i;
for(i = 0; i < REQUIRED_INTERRUPTS; i++) { for (i = 0; i < REQUIRED_INTERRUPTS; i++) {
if(pci_data.irq_mapping[i] == irq) { if (pci_data.irq_mapping[i] == irq) {
return i; return i;
} }
} }
...@@ -172,7 +162,7 @@ static int claim_msi(struct pci_dev *pdev) ...@@ -172,7 +162,7 @@ static int claim_msi(struct pci_dev *pdev)
{ {
int err = 0, i; int err = 0, i;
for(i = 0; i < REQUIRED_INTERRUPTS; i++) { for (i = 0; i < REQUIRED_INTERRUPTS; i++) {
pci_data.irq_mapping[i] = -1; pci_data.irq_mapping[i] = -1;
} }
...@@ -186,9 +176,11 @@ static int claim_msi(struct pci_dev *pdev) ...@@ -186,9 +176,11 @@ static int claim_msi(struct pci_dev *pdev)
fflink_warn("Got %d MSI vectors\n", err); fflink_warn("Got %d MSI vectors\n", err);
} }
for(i = 0; i < REQUIRED_INTERRUPTS; i++) { for (i = 0; i < REQUIRED_INTERRUPTS; i++) {
err = register_intr_handler(pdev, i); err = register_intr_handler(pdev, i);
if (err) { if (err == -2) fflink_warn("Interrupt number %d unused\n", i);
else if (err) {
fflink_warn("Cannot request Interrupt number %d\n", i); fflink_warn("Cannot request Interrupt number %d\n", i);
goto error_pci_req_irq; goto error_pci_req_irq;
} }
...@@ -215,22 +207,22 @@ static void report_link_status(struct pci_dev *pdev) ...@@ -215,22 +207,22 @@ static void report_link_status(struct pci_dev *pdev)
pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &ctrl_reg); pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &ctrl_reg);
/* report current link settings */ /* report current link settings */
if((ctrl_reg & PCI_EXP_LNKSTA_NLW_X1) > 0) if ((ctrl_reg & PCI_EXP_LNKSTA_NLW_X1) > 0)
fflink_notice("Current Link Width x1\n"); fflink_notice("Current Link Width x1\n");
else if((ctrl_reg & PCI_EXP_LNKSTA_NLW_X2) > 0) else if ((ctrl_reg & PCI_EXP_LNKSTA_NLW_X2) > 0)
fflink_notice("Current Link Width x2\n"); fflink_notice("Current Link Width x2\n");
else if((ctrl_reg & PCI_EXP_LNKSTA_NLW_X4) > 0) else if ((ctrl_reg & PCI_EXP_LNKSTA_NLW_X4) > 0)
fflink_notice("Current Link Width x4\n"); fflink_notice("Current Link Width x4\n");
else if((ctrl_reg & PCI_EXP_LNKSTA_NLW_X8) > 0) else if ((ctrl_reg & PCI_EXP_LNKSTA_NLW_X8) > 0)
fflink_notice("Current Link Width x8\n"); fflink_notice("Current Link Width x8\n");
else else
fflink_warn("Current Link Width error\n"); fflink_warn("Current Link Width error\n");
if((ctrl_reg & PCI_EXP_LNKSTA_CLS_8_0GB) > 0) if ((ctrl_reg & PCI_EXP_LNKSTA_CLS_8_0GB) > 0)
fflink_notice("Current Link Speed 8.0GT/s\n"); fflink_notice("Current Link Speed 8.0GT/s\n");
else if((ctrl_reg & PCI_EXP_LNKSTA_CLS_5_0GB) > 0) else if ((ctrl_reg & PCI_EXP_LNKSTA_CLS_5_0GB) > 0)
fflink_notice("Current Link Speed 5.0GT/s\n"); fflink_notice("Current Link Speed 5.0GT/s\n");
else if((ctrl_reg & PCI_EXP_LNKSTA_CLS_2_5GB) > 0) else if ((ctrl_reg & PCI_EXP_LNKSTA_CLS_2_5GB) > 0)
fflink_notice("Current Link Speed 2.5GT/s\n"); fflink_notice("Current Link Speed 2.5GT/s\n");
else else
fflink_warn("Current Link Speed error\n"); fflink_warn("Current Link Speed error\n");
...@@ -246,7 +238,7 @@ static void report_link_status(struct pci_dev *pdev) ...@@ -246,7 +238,7 @@ static void report_link_status(struct pci_dev *pdev)
* */ * */
struct pci_dev* get_pcie_dev(void) struct pci_dev* get_pcie_dev(void)
{ {
if(IS_ERR(pci_data.pdev)) if (IS_ERR(pci_data.pdev))
fflink_warn("PCIe dev not initialized\n"); fflink_warn("PCIe dev not initialized\n");
return pci_data.pdev; return pci_data.pdev;
...@@ -259,7 +251,7 @@ struct pci_dev* get_pcie_dev(void) ...@@ -259,7 +251,7 @@ struct pci_dev* get_pcie_dev(void)
* */ * */
void * get_virt_bar0_addr(void) void * get_virt_bar0_addr(void)
{ {
if(IS_ERR(pci_data.kvirt_addr_bar0)) if (IS_ERR(pci_data.kvirt_addr_bar0))
fflink_warn("Bar 0 address not valid\n"); fflink_warn("Bar 0 address not valid\n");
return pci_data.kvirt_addr_bar0; return pci_data.kvirt_addr_bar0;
...@@ -274,13 +266,22 @@ void * get_virt_bar0_addr(void) ...@@ -274,13 +266,22 @@ void * get_virt_bar0_addr(void)
* */ * */
void pcie_writel(unsigned long data, void * addr) void pcie_writel(unsigned long data, void * addr)
{ {
if(pci_data.phy_len_bar0 <= (long unsigned)addr) { if (pci_data.phy_len_bar0 <= (long unsigned)addr) {
fflink_warn("Illegal write request to address 0x%lx\n", (long unsigned)addr); fflink_warn("Illegal write request to address 0x%lx\n", (long unsigned)addr);
return; return;
} }
writel(data, pci_data.kvirt_addr_bar0 + (unsigned long long) addr); writel(data, pci_data.kvirt_addr_bar0 + (unsigned long long) addr);
} }