24 #include <linux/errno.h>
27 #include <linux/kernel.h>
28 #include <linux/module.h>
29 #include <linux/pci.h>
60 if (len !=
sizeof(
u32))
79 static int tsi721_lcwrite(
struct rio_mport *mport,
int index,
u32 offset,
84 if (len !=
sizeof(
u32))
108 u16 destid,
u8 hopcount,
u32 offset,
int len,
109 u32 *data,
int do_wr)
120 bd_ptr = priv->
mdma.bd_base;
132 bd_ptr[0].
data[0] = 0xffffffff;
145 if (++i >= 5000000) {
147 "%s : DMA[%d] read timeout ch_status=%x\n",
148 __func__, priv->
mdma.ch_id, ch_stat);
160 dev_dbg(&priv->
pdev->dev,
"%s : DMA ABORT ch_stat=%x\n",
162 dev_dbg(&priv->
pdev->dev,
"OP=%d : destid=%x hc=%x off=%x\n",
204 static int tsi721_cread_dma(
struct rio_mport *mport,
int index,
u16 destid,
205 u8 hopcount,
u32 offset,
int len,
u32 *data)
209 return tsi721_maint_dma(priv, mport->
sys_size, destid, hopcount,
210 offset, len, data, 0);
227 static int tsi721_cwrite_dma(
struct rio_mport *mport,
int index,
u16 destid,
228 u8 hopcount,
u32 offset,
int len,
u32 data)
233 return tsi721_maint_dma(priv, mport->
sys_size, destid, hopcount,
234 offset, len, &temp, 1);
246 tsi721_pw_handler(
struct rio_mport *mport)
298 pr_debug(
"%s : Port-Write Message:", __func__);
300 pr_debug(
"0x%02x: %08x %08x %08x %08x", i*4,
301 msg_buffer[i], msg_buffer[i + 1],
302 msg_buffer[i + 2], msg_buffer[i + 3]);
348 static int tsi721_dsend(
struct rio_mport *mport,
int index,
358 "Send Doorbell 0x%04x to destID 0x%x\n", data, destid);
373 tsi721_dbell_handler(
struct rio_mport *mport)
389 static void tsi721_db_dpc(
struct work_struct *work)
412 while (wr_ptr != rd_ptr) {
417 idb.msg = *idb_entry;
434 "spurious inb doorbell, sid %2.2x tid %2.2x"
453 if (wr_ptr != rd_ptr)
487 tsi721_dbell_handler(mport);
490 "Unsupported SR_CH_INT %x\n", intval);
518 tsi721_imsg_handler(priv, ch);
535 tsi721_omsg_handler(priv, ch);
544 tsi721_pw_handler(mport);
547 #ifdef CONFIG_RAPIDIO_DMA_ENGINE
553 "IRQ from DMA channel 0x%08x\n", dev_ch_int);
566 static void tsi721_interrupts_init(
struct tsi721_device *priv)
581 #ifdef CONFIG_RAPIDIO_DMA_ENGINE
583 (TSI721_INT_BDMA_CHAN_M &
593 intr = TSI721_DEV_INT_SR2PC_CH | TSI721_DEV_INT_SRIO |
600 #ifdef CONFIG_PCI_MSI
608 static irqreturn_t tsi721_omsg_msix(
int irq,
void *ptr)
613 mbox = (irq - priv->msix[TSI721_VECT_OMB0_DONE].vector) % RIO_MAX_MBOX;
614 tsi721_omsg_handler(priv, mbox);
625 static irqreturn_t tsi721_imsg_msix(
int irq,
void *ptr)
630 mbox = (irq - priv->msix[TSI721_VECT_IMB0_RCV].vector) % RIO_MAX_MBOX;
631 tsi721_imsg_handler(priv, mbox + 4);
642 static irqreturn_t tsi721_srio_msix(
int irq,
void *ptr)
650 tsi721_pw_handler((
struct rio_mport *)ptr);
664 static irqreturn_t tsi721_sr2pc_ch_msix(
int irq,
void *ptr)
671 if (sr_ch_int & TSI721_SR_CHINT_IDBQRCV)
672 tsi721_dbell_handler((
struct rio_mport *)ptr);
690 static int tsi721_request_msix(
struct rio_mport *mport)
695 err =
request_irq(priv->msix[TSI721_VECT_IDB].vector,
696 tsi721_sr2pc_ch_msix, 0,
697 priv->msix[TSI721_VECT_IDB].irq_name, (
void *)mport);
701 err =
request_irq(priv->msix[TSI721_VECT_PWRX].vector,
703 priv->msix[TSI721_VECT_PWRX].irq_name, (
void *)mport);
706 priv->msix[TSI721_VECT_IDB].vector,
721 struct msix_entry
entries[TSI721_VECT_MAX];
726 entries[TSI721_VECT_PWRX].entry = TSI721_MSIX_SRIO_MAC_INT;
735 entries[TSI721_VECT_IMB0_RCV +
i].entry =
736 TSI721_MSIX_IMSG_DQ_RCV(i + 4);
737 entries[TSI721_VECT_IMB0_INT +
i].entry =
738 TSI721_MSIX_IMSG_INT(i + 4);
739 entries[TSI721_VECT_OMB0_DONE +
i].entry =
740 TSI721_MSIX_OMSG_DONE(i);
741 entries[TSI721_VECT_OMB0_INT +
i].entry =
742 TSI721_MSIX_OMSG_INT(i);
745 #ifdef CONFIG_RAPIDIO_DMA_ENGINE
752 entries[TSI721_VECT_DMA0_DONE +
i].entry =
753 TSI721_MSIX_DMACH_DONE(i);
754 entries[TSI721_VECT_DMA0_INT +
i].entry =
755 TSI721_MSIX_DMACH_INT(i);
763 "Only %d MSI-X vectors available, "
764 "not using MSI-X\n", err);
767 "Failed to enable MSI-X (err=%d)\n", err);
774 priv->msix[TSI721_VECT_IDB].vector =
entries[TSI721_VECT_IDB].vector;
775 snprintf(priv->msix[TSI721_VECT_IDB].irq_name, IRQ_DEVICE_NAME_MAX,
777 priv->msix[TSI721_VECT_PWRX].vector =
entries[TSI721_VECT_PWRX].vector;
778 snprintf(priv->msix[TSI721_VECT_PWRX].irq_name, IRQ_DEVICE_NAME_MAX,
782 priv->msix[TSI721_VECT_IMB0_RCV +
i].vector =
783 entries[TSI721_VECT_IMB0_RCV +
i].vector;
784 snprintf(priv->msix[TSI721_VECT_IMB0_RCV + i].irq_name,
785 IRQ_DEVICE_NAME_MAX,
DRV_NAME "-imbr%d@pci:%s",
786 i, pci_name(priv->
pdev));
788 priv->msix[TSI721_VECT_IMB0_INT +
i].vector =
789 entries[TSI721_VECT_IMB0_INT +
i].vector;
790 snprintf(priv->msix[TSI721_VECT_IMB0_INT + i].irq_name,
791 IRQ_DEVICE_NAME_MAX,
DRV_NAME "-imbi%d@pci:%s",
792 i, pci_name(priv->
pdev));
794 priv->msix[TSI721_VECT_OMB0_DONE +
i].vector =
795 entries[TSI721_VECT_OMB0_DONE +
i].vector;
796 snprintf(priv->msix[TSI721_VECT_OMB0_DONE + i].irq_name,
797 IRQ_DEVICE_NAME_MAX,
DRV_NAME "-ombd%d@pci:%s",
798 i, pci_name(priv->
pdev));
800 priv->msix[TSI721_VECT_OMB0_INT +
i].vector =
801 entries[TSI721_VECT_OMB0_INT +
i].vector;
802 snprintf(priv->msix[TSI721_VECT_OMB0_INT + i].irq_name,
803 IRQ_DEVICE_NAME_MAX,
DRV_NAME "-ombi%d@pci:%s",
804 i, pci_name(priv->
pdev));
807 #ifdef CONFIG_RAPIDIO_DMA_ENGINE
809 priv->msix[TSI721_VECT_DMA0_DONE +
i].vector =
810 entries[TSI721_VECT_DMA0_DONE +
i].vector;
811 snprintf(priv->msix[TSI721_VECT_DMA0_DONE + i].irq_name,
812 IRQ_DEVICE_NAME_MAX,
DRV_NAME "-dmad%d@pci:%s",
813 i, pci_name(priv->
pdev));
815 priv->msix[TSI721_VECT_DMA0_INT +
i].vector =
816 entries[TSI721_VECT_DMA0_INT +
i].vector;
817 snprintf(priv->msix[TSI721_VECT_DMA0_INT + i].irq_name,
818 IRQ_DEVICE_NAME_MAX,
DRV_NAME "-dmai%d@pci:%s",
819 i, pci_name(priv->
pdev));
827 static int tsi721_request_irq(
struct rio_mport *mport)
832 #ifdef CONFIG_PCI_MSI
834 err = tsi721_request_msix(mport);
843 "Unable to allocate interrupt, Error: %d\n", err);
855 static void tsi721_init_pc2sr_mapping(
struct tsi721_device *priv)
885 ((
u64)lstart & (size - 1)) || (rstart & (size - 1)))
895 if (i >= TSI721_IBWIN_NUM) {
897 "Unable to find free inbound window\n");
912 "Configured IBWIN%d mapping (RIO_0x%llx -> PCIe_0x%llx)\n",
913 i, rstart, (
unsigned long long)lstart);
923 static void tsi721_rio_unmap_inb_mem(
struct rio_mport *mport,
936 addr = (
u64)regval << 32;
940 if (addr == (
u64)lstart) {
955 static void tsi721_init_sr2pc_mapping(
struct tsi721_device *priv)
971 static int tsi721_port_write_init(
struct tsi721_device *priv)
978 dev_err(&priv->
pdev->dev,
"PW FIFO allocation failed\n");
1005 dev_dbg(&priv->
pdev->dev,
"Allocated IDB buffer @ %p (phys = %llx)\n",
1024 static void tsi721_doorbell_free(
struct tsi721_device *priv)
1043 static int tsi721_bdma_maint_init(
struct tsi721_device *priv)
1053 "Init Block DMA Engine for Maintenance requests, CH%d\n",
1064 bd_ptr = dma_zalloc_coherent(&priv->
pdev->dev,
1070 priv->
mdma.bd_num = bd_num;
1071 priv->
mdma.bd_phys = bd_phys;
1072 priv->
mdma.bd_base = bd_ptr;
1074 dev_dbg(&priv->
pdev->dev,
"DMA descriptors @ %p (phys = %llx)\n",
1075 bd_ptr, (
unsigned long long)bd_phys);
1081 sts_ptr = dma_zalloc_coherent(&priv->
pdev->dev,
1093 priv->
mdma.sts_phys = sts_phys;
1094 priv->
mdma.sts_base = sts_ptr;
1095 priv->
mdma.sts_size = sts_size;
1098 "desc status FIFO @ %p (phys = %llx) size=0x%x\n",
1099 sts_ptr, (
unsigned long long)sts_phys, sts_size);
1132 static int tsi721_bdma_maint_free(
struct tsi721_device *priv)
1143 if (ch_stat & TSI721_DMAC_STS_RUN)
1165 tsi721_imsg_interrupt_enable(
struct tsi721_device *priv,
int ch,
1195 tsi721_imsg_interrupt_disable(
struct tsi721_device *priv,
int ch,
1226 tsi721_omsg_interrupt_enable(
struct tsi721_device *priv,
int ch,
1256 tsi721_omsg_interrupt_disable(
struct tsi721_device *priv,
int ch,
1295 void *
buffer,
size_t len)
1316 if (tx_slot % 4 == 0)
1321 (0
xe << 12) | (len & 0xff8));
1354 static void tsi721_omsg_handler(
struct tsi721_device *priv,
int ch)
1364 "OB MBOX%d: Status FIFO is full\n", ch);
1368 u64 *sts_ptr, last_ptr = 0, prev_ptr = 0;
1377 srd_ptr = priv->
omsg_ring[ch].sts_rdptr;
1380 while (sts_ptr[j]) {
1381 for (i = 0; i < 8 && sts_ptr[
j]; i++, j++) {
1382 prev_ptr = last_ptr;
1388 srd_ptr %= priv->
omsg_ring[ch].sts_size;
1395 priv->
omsg_ring[ch].sts_rdptr = srd_ptr;
1398 if (!priv->
mport->outb_msg[ch].mcback)
1403 tx_slot = (last_ptr - (
u64)priv->
omsg_ring[ch].omd_phys)/
1411 if (tx_slot == priv->
omsg_ring[ch].size) {
1413 tx_slot = (prev_ptr -
1422 if (tx_slot == priv->
omsg_ring[ch].size)
1425 priv->
mport->outb_msg[ch].mcback(priv->
mport,
1438 dev_dbg(&priv->
pdev->dev,
"OB MSG ABORT ch_stat=%x\n",
1448 if (priv->
mport->outb_msg[ch].mcback)
1449 priv->
mport->outb_msg[ch].mcback(priv->
mport,
1482 static int tsi721_open_outb_mbox(
struct rio_mport *mport,
void *
dev_id,
1503 for (i = 0; i <
entries; i++) {
1511 "Unable to allocate OB MSG data buffer for"
1525 "Unable to allocate OB MSG descriptor memory "
1526 "for MBOX%d\n", mbox);
1541 "Unable to allocate OB MSG descriptor status FIFO "
1542 "for MBOX%d\n", mbox);
1569 #ifdef CONFIG_PCI_MSI
1573 priv->msix[TSI721_VECT_OMB0_DONE + mbox].vector,
1574 tsi721_omsg_msix, 0,
1575 priv->msix[TSI721_VECT_OMB0_DONE + mbox].irq_name,
1580 "Unable to allocate MSI-X interrupt for "
1581 "OBOX%d-DONE\n", mbox);
1585 rc =
request_irq(priv->msix[TSI721_VECT_OMB0_INT + mbox].vector,
1586 tsi721_omsg_msix, 0,
1587 priv->msix[TSI721_VECT_OMB0_INT + mbox].irq_name,
1592 "Unable to allocate MSI-X interrupt for "
1593 "MBOX%d-INT\n", mbox);
1595 priv->msix[TSI721_VECT_OMB0_DONE + mbox].vector,
1610 TSI721_OBDMAC_DPTRL_MASK);
1625 #ifdef CONFIG_PCI_MSI
1645 if (priv->
omsg_ring[mbox].omq_base[i]) {
1664 static void tsi721_close_outb_mbox(
struct rio_mport *mport,
int mbox)
1677 #ifdef CONFIG_PCI_MSI
1679 free_irq(priv->msix[TSI721_VECT_OMB0_DONE + mbox].vector,
1681 free_irq(priv->msix[TSI721_VECT_OMB0_INT + mbox].vector,
1705 if (priv->
omsg_ring[mbox].omq_base[i]) {
1723 static void tsi721_imsg_handler(
struct tsi721_device *priv,
int ch)
1742 "IB MBOX%d IB free queue low\n", mbox);
1749 priv->
mport->inb_msg[mbox].mcback)
1751 priv->
imsg_ring[mbox].dev_id, mbox, -1);
1762 spin_unlock(&priv->
imsg_ring[mbox].lock);
1772 static int tsi721_open_inb_mbox(
struct rio_mport *mport,
void *dev_id,
1773 int mbox,
int entries)
1807 "Failed to allocate buffers for IB MBOX%d\n", mbox);
1821 "Failed to allocate free queue for IB MBOX%d\n", mbox);
1834 "Failed to allocate descriptor memory for IB MBOX%d\n",
1884 #ifdef CONFIG_PCI_MSI
1887 rc =
request_irq(priv->msix[TSI721_VECT_IMB0_RCV + mbox].vector,
1888 tsi721_imsg_msix, 0,
1889 priv->msix[TSI721_VECT_IMB0_RCV + mbox].irq_name,
1894 "Unable to allocate MSI-X interrupt for "
1895 "IBOX%d-DONE\n", mbox);
1899 rc =
request_irq(priv->msix[TSI721_VECT_IMB0_INT + mbox].vector,
1900 tsi721_imsg_msix, 0,
1901 priv->msix[TSI721_VECT_IMB0_INT + mbox].irq_name,
1906 "Unable to allocate MSI-X interrupt for "
1907 "IBOX%d-INT\n", mbox);
1909 priv->msix[TSI721_VECT_IMB0_RCV + mbox].vector,
1928 #ifdef CONFIG_PCI_MSI
1963 static void tsi721_close_inb_mbox(
struct rio_mport *mport,
int mbox)
1978 #ifdef CONFIG_PCI_MSI
1980 free_irq(priv->msix[TSI721_VECT_IMB0_RCV + mbox].vector,
1982 free_irq(priv->msix[TSI721_VECT_IMB0_INT + mbox].vector,
1988 for (rx_slot = 0; rx_slot < priv->
imsg_ring[
mbox].size; rx_slot++)
2022 static int tsi721_add_inb_buffer(
struct rio_mport *mport,
int mbox,
void *
buf)
2029 if (priv->
imsg_ring[mbox].imq_base[rx_slot]) {
2031 "Error adding inbound buffer %d, buffer exists\n",
2053 static void *tsi721_get_inb_message(
struct rio_mport *mport,
int mbox)
2058 void *rx_virt =
NULL;
2076 if (++rx_slot == priv->
imsg_ring[mbox].size)
2091 memcpy(buf, rx_virt, msg_size);
2215 dev_dbg(&pdev->
dev,
"Unable to allocate memory for rio_ops\n");
2219 ops->
lcread = tsi721_lcread;
2220 ops->
lcwrite = tsi721_lcwrite;
2221 ops->
cread = tsi721_cread_dma;
2222 ops->
cwrite = tsi721_cwrite_dma;
2223 ops->
dsend = tsi721_dsend;
2231 ops->
map_inb = tsi721_rio_map_inb_mem;
2232 ops->
unmap_inb = tsi721_rio_unmap_inb_mem;
2237 dev_dbg(&pdev->
dev,
"Unable to allocate memory for mport\n");
2245 mport->
priv = (
void *)priv;
2247 priv->
mport = mport;
2249 INIT_LIST_HEAD(&mport->
dbells);
2259 #ifdef CONFIG_PCI_MSI
2260 if (!tsi721_enable_msix(priv))
2262 else if (!pci_enable_msi(pdev))
2266 "MSI/MSI-X is not available. Using legacy INTx.\n");
2269 err = tsi721_request_irq(mport);
2272 tsi721_interrupts_init(priv);
2275 dev_err(&pdev->
dev,
"Unable to get assigned PCI IRQ "
2276 "vector %02X err=0x%x\n", pdev->
irq, err);
2280 #ifdef CONFIG_RAPIDIO_DMA_ENGINE
2313 dev_err(&pdev->
dev,
"Failed to allocate memory for device\n");
2320 dev_err(&pdev->
dev,
"Failed to enable PCI device\n");
2330 dev_dbg(&pdev->
dev,
"res[%d] @ 0x%llx (0x%lx, 0x%lx)\n",
2346 "Missing or misconfigured CSR BAR0, aborting.\n");
2348 goto err_disable_pdev;
2356 "Missing or misconfigured Doorbell BAR1, aborting.\n");
2358 goto err_disable_pdev;
2370 dev_info(&pdev->
dev,
"Outbound BAR2 is not used but enabled.\n");
2375 dev_info(&pdev->
dev,
"Outbound BAR4 is not used but enabled.\n");
2380 dev_err(&pdev->
dev,
"Cannot obtain PCI resources, "
2382 goto err_disable_pdev;
2390 "Unable to map device registers space, aborting\n");
2398 "Unable to map outbound doorbells space, aborting\n");
2400 goto err_unmap_bars;
2408 goto err_unmap_bars;
2411 if (pci_set_consistent_dma_mask(pdev,
DMA_BIT_MASK(32)))
2412 dev_info(&pdev->
dev,
"Unable to set consistent DMA mask\n");
2414 err = pci_set_consistent_dma_mask(pdev,
DMA_BIT_MASK(64));
2416 dev_info(&pdev->
dev,
"Unable to set consistent DMA mask\n");
2419 BUG_ON(!pci_is_pcie(pdev));
2441 tsi721_disable_ints(priv);
2443 tsi721_init_pc2sr_mapping(priv);
2444 tsi721_init_sr2pc_mapping(priv);
2446 if (tsi721_bdma_maint_init(priv)) {
2447 dev_err(&pdev->
dev,
"BDMA initialization failed, aborting\n");
2449 goto err_unmap_bars;
2452 err = tsi721_doorbell_init(priv);
2456 tsi721_port_write_init(priv);
2458 err = tsi721_messages_init(priv);
2460 goto err_free_consistent;
2462 err = tsi721_setup_mport(priv);
2464 goto err_free_consistent;
2468 err_free_consistent:
2469 tsi721_doorbell_free(priv);
2471 tsi721_bdma_maint_free(priv);
2497 .id_table = tsi721_pci_tbl,
2498 .probe = tsi721_probe,
2501 static int __init tsi721_init(
void)
2503 return pci_register_driver(&tsi721_driver);
2506 static void __exit tsi721_exit(
void)