aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ntb/ntb_transport.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ntb/ntb_transport.c')
-rw-r--r--drivers/ntb/ntb_transport.c175
1 files changed, 114 insertions, 61 deletions
diff --git a/drivers/ntb/ntb_transport.c b/drivers/ntb/ntb_transport.c
index e0bdfd7f9930..f8d7081ee301 100644
--- a/drivers/ntb/ntb_transport.c
+++ b/drivers/ntb/ntb_transport.c
@@ -58,7 +58,7 @@
58#include <linux/ntb.h> 58#include <linux/ntb.h>
59#include "ntb_hw.h" 59#include "ntb_hw.h"
60 60
61#define NTB_TRANSPORT_VERSION 2 61#define NTB_TRANSPORT_VERSION 3
62 62
63static unsigned int transport_mtu = 0x401E; 63static unsigned int transport_mtu = 0x401E;
64module_param(transport_mtu, uint, 0644); 64module_param(transport_mtu, uint, 0644);
@@ -173,10 +173,13 @@ struct ntb_payload_header {
173 173
174enum { 174enum {
175 VERSION = 0, 175 VERSION = 0,
176 MW0_SZ,
177 MW1_SZ,
178 NUM_QPS,
179 QP_LINKS, 176 QP_LINKS,
177 NUM_QPS,
178 NUM_MWS,
179 MW0_SZ_HIGH,
180 MW0_SZ_LOW,
181 MW1_SZ_HIGH,
182 MW1_SZ_LOW,
180 MAX_SPAD, 183 MAX_SPAD,
181}; 184};
182 185
@@ -297,7 +300,7 @@ int ntb_register_client_dev(char *device_name)
297{ 300{
298 struct ntb_transport_client_dev *client_dev; 301 struct ntb_transport_client_dev *client_dev;
299 struct ntb_transport *nt; 302 struct ntb_transport *nt;
300 int rc; 303 int rc, i = 0;
301 304
302 if (list_empty(&ntb_transport_list)) 305 if (list_empty(&ntb_transport_list))
303 return -ENODEV; 306 return -ENODEV;
@@ -315,7 +318,7 @@ int ntb_register_client_dev(char *device_name)
315 dev = &client_dev->dev; 318 dev = &client_dev->dev;
316 319
317 /* setup and register client devices */ 320 /* setup and register client devices */
318 dev_set_name(dev, "%s", device_name); 321 dev_set_name(dev, "%s%d", device_name, i);
319 dev->bus = &ntb_bus_type; 322 dev->bus = &ntb_bus_type;
320 dev->release = ntb_client_release; 323 dev->release = ntb_client_release;
321 dev->parent = &ntb_query_pdev(nt->ndev)->dev; 324 dev->parent = &ntb_query_pdev(nt->ndev)->dev;
@@ -327,6 +330,7 @@ int ntb_register_client_dev(char *device_name)
327 } 330 }
328 331
329 list_add_tail(&client_dev->entry, &nt->client_devs); 332 list_add_tail(&client_dev->entry, &nt->client_devs);
333 i++;
330 } 334 }
331 335
332 return 0; 336 return 0;
@@ -486,12 +490,13 @@ static void ntb_transport_setup_qp_mw(struct ntb_transport *nt,
486 (qp_num / NTB_NUM_MW * rx_size); 490 (qp_num / NTB_NUM_MW * rx_size);
487 rx_size -= sizeof(struct ntb_rx_info); 491 rx_size -= sizeof(struct ntb_rx_info);
488 492
489 qp->rx_buff = qp->remote_rx_info + sizeof(struct ntb_rx_info); 493 qp->rx_buff = qp->remote_rx_info + 1;
490 qp->rx_max_frame = min(transport_mtu, rx_size); 494 /* Due to housekeeping, there must be atleast 2 buffs */
495 qp->rx_max_frame = min(transport_mtu, rx_size / 2);
491 qp->rx_max_entry = rx_size / qp->rx_max_frame; 496 qp->rx_max_entry = rx_size / qp->rx_max_frame;
492 qp->rx_index = 0; 497 qp->rx_index = 0;
493 498
494 qp->remote_rx_info->entry = qp->rx_max_entry; 499 qp->remote_rx_info->entry = qp->rx_max_entry - 1;
495 500
496 /* setup the hdr offsets with 0's */ 501 /* setup the hdr offsets with 0's */
497 for (i = 0; i < qp->rx_max_entry; i++) { 502 for (i = 0; i < qp->rx_max_entry; i++) {
@@ -502,6 +507,19 @@ static void ntb_transport_setup_qp_mw(struct ntb_transport *nt,
502 507
503 qp->rx_pkts = 0; 508 qp->rx_pkts = 0;
504 qp->tx_pkts = 0; 509 qp->tx_pkts = 0;
510 qp->tx_index = 0;
511}
512
513static void ntb_free_mw(struct ntb_transport *nt, int num_mw)
514{
515 struct ntb_transport_mw *mw = &nt->mw[num_mw];
516 struct pci_dev *pdev = ntb_query_pdev(nt->ndev);
517
518 if (!mw->virt_addr)
519 return;
520
521 dma_free_coherent(&pdev->dev, mw->size, mw->virt_addr, mw->dma_addr);
522 mw->virt_addr = NULL;
505} 523}
506 524
507static int ntb_set_mw(struct ntb_transport *nt, int num_mw, unsigned int size) 525static int ntb_set_mw(struct ntb_transport *nt, int num_mw, unsigned int size)
@@ -509,12 +527,20 @@ static int ntb_set_mw(struct ntb_transport *nt, int num_mw, unsigned int size)
509 struct ntb_transport_mw *mw = &nt->mw[num_mw]; 527 struct ntb_transport_mw *mw = &nt->mw[num_mw];
510 struct pci_dev *pdev = ntb_query_pdev(nt->ndev); 528 struct pci_dev *pdev = ntb_query_pdev(nt->ndev);
511 529
530 /* No need to re-setup */
531 if (mw->size == ALIGN(size, 4096))
532 return 0;
533
534 if (mw->size != 0)
535 ntb_free_mw(nt, num_mw);
536
512 /* Alloc memory for receiving data. Must be 4k aligned */ 537 /* Alloc memory for receiving data. Must be 4k aligned */
513 mw->size = ALIGN(size, 4096); 538 mw->size = ALIGN(size, 4096);
514 539
515 mw->virt_addr = dma_alloc_coherent(&pdev->dev, mw->size, &mw->dma_addr, 540 mw->virt_addr = dma_alloc_coherent(&pdev->dev, mw->size, &mw->dma_addr,
516 GFP_KERNEL); 541 GFP_KERNEL);
517 if (!mw->virt_addr) { 542 if (!mw->virt_addr) {
543 mw->size = 0;
518 dev_err(&pdev->dev, "Unable to allocate MW buffer of size %d\n", 544 dev_err(&pdev->dev, "Unable to allocate MW buffer of size %d\n",
519 (int) mw->size); 545 (int) mw->size);
520 return -ENOMEM; 546 return -ENOMEM;
@@ -604,25 +630,31 @@ static void ntb_transport_link_work(struct work_struct *work)
604 u32 val; 630 u32 val;
605 int rc, i; 631 int rc, i;
606 632
607 /* send the local info */ 633 /* send the local info, in the opposite order of the way we read it */
608 rc = ntb_write_remote_spad(ndev, VERSION, NTB_TRANSPORT_VERSION); 634 for (i = 0; i < NTB_NUM_MW; i++) {
609 if (rc) { 635 rc = ntb_write_remote_spad(ndev, MW0_SZ_HIGH + (i * 2),
610 dev_err(&pdev->dev, "Error writing %x to remote spad %d\n", 636 ntb_get_mw_size(ndev, i) >> 32);
611 0, VERSION); 637 if (rc) {
612 goto out; 638 dev_err(&pdev->dev, "Error writing %u to remote spad %d\n",
613 } 639 (u32)(ntb_get_mw_size(ndev, i) >> 32),
640 MW0_SZ_HIGH + (i * 2));
641 goto out;
642 }
614 643
615 rc = ntb_write_remote_spad(ndev, MW0_SZ, ntb_get_mw_size(ndev, 0)); 644 rc = ntb_write_remote_spad(ndev, MW0_SZ_LOW + (i * 2),
616 if (rc) { 645 (u32) ntb_get_mw_size(ndev, i));
617 dev_err(&pdev->dev, "Error writing %x to remote spad %d\n", 646 if (rc) {
618 (u32) ntb_get_mw_size(ndev, 0), MW0_SZ); 647 dev_err(&pdev->dev, "Error writing %u to remote spad %d\n",
619 goto out; 648 (u32) ntb_get_mw_size(ndev, i),
649 MW0_SZ_LOW + (i * 2));
650 goto out;
651 }
620 } 652 }
621 653
622 rc = ntb_write_remote_spad(ndev, MW1_SZ, ntb_get_mw_size(ndev, 1)); 654 rc = ntb_write_remote_spad(ndev, NUM_MWS, NTB_NUM_MW);
623 if (rc) { 655 if (rc) {
624 dev_err(&pdev->dev, "Error writing %x to remote spad %d\n", 656 dev_err(&pdev->dev, "Error writing %x to remote spad %d\n",
625 (u32) ntb_get_mw_size(ndev, 1), MW1_SZ); 657 NTB_NUM_MW, NUM_MWS);
626 goto out; 658 goto out;
627 } 659 }
628 660
@@ -633,16 +665,10 @@ static void ntb_transport_link_work(struct work_struct *work)
633 goto out; 665 goto out;
634 } 666 }
635 667
636 rc = ntb_read_local_spad(nt->ndev, QP_LINKS, &val); 668 rc = ntb_write_remote_spad(ndev, VERSION, NTB_TRANSPORT_VERSION);
637 if (rc) {
638 dev_err(&pdev->dev, "Error reading spad %d\n", QP_LINKS);
639 goto out;
640 }
641
642 rc = ntb_write_remote_spad(ndev, QP_LINKS, val);
643 if (rc) { 669 if (rc) {
644 dev_err(&pdev->dev, "Error writing %x to remote spad %d\n", 670 dev_err(&pdev->dev, "Error writing %x to remote spad %d\n",
645 val, QP_LINKS); 671 NTB_TRANSPORT_VERSION, VERSION);
646 goto out; 672 goto out;
647 } 673 }
648 674
@@ -667,33 +693,43 @@ static void ntb_transport_link_work(struct work_struct *work)
667 goto out; 693 goto out;
668 dev_dbg(&pdev->dev, "Remote max number of qps = %d\n", val); 694 dev_dbg(&pdev->dev, "Remote max number of qps = %d\n", val);
669 695
670 rc = ntb_read_remote_spad(ndev, MW0_SZ, &val); 696 rc = ntb_read_remote_spad(ndev, NUM_MWS, &val);
671 if (rc) { 697 if (rc) {
672 dev_err(&pdev->dev, "Error reading remote spad %d\n", MW0_SZ); 698 dev_err(&pdev->dev, "Error reading remote spad %d\n", NUM_MWS);
673 goto out; 699 goto out;
674 } 700 }
675 701
676 if (!val) 702 if (val != NTB_NUM_MW)
677 goto out; 703 goto out;
678 dev_dbg(&pdev->dev, "Remote MW0 size = %d\n", val); 704 dev_dbg(&pdev->dev, "Remote number of mws = %d\n", val);
679 705
680 rc = ntb_set_mw(nt, 0, val); 706 for (i = 0; i < NTB_NUM_MW; i++) {
681 if (rc) 707 u64 val64;
682 goto out;
683 708
684 rc = ntb_read_remote_spad(ndev, MW1_SZ, &val); 709 rc = ntb_read_remote_spad(ndev, MW0_SZ_HIGH + (i * 2), &val);
685 if (rc) { 710 if (rc) {
686 dev_err(&pdev->dev, "Error reading remote spad %d\n", MW1_SZ); 711 dev_err(&pdev->dev, "Error reading remote spad %d\n",
687 goto out; 712 MW0_SZ_HIGH + (i * 2));
688 } 713 goto out1;
714 }
689 715
690 if (!val) 716 val64 = (u64) val << 32;
691 goto out;
692 dev_dbg(&pdev->dev, "Remote MW1 size = %d\n", val);
693 717
694 rc = ntb_set_mw(nt, 1, val); 718 rc = ntb_read_remote_spad(ndev, MW0_SZ_LOW + (i * 2), &val);
695 if (rc) 719 if (rc) {
696 goto out; 720 dev_err(&pdev->dev, "Error reading remote spad %d\n",
721 MW0_SZ_LOW + (i * 2));
722 goto out1;
723 }
724
725 val64 |= val;
726
727 dev_dbg(&pdev->dev, "Remote MW%d size = %llu\n", i, val64);
728
729 rc = ntb_set_mw(nt, i, val64);
730 if (rc)
731 goto out1;
732 }
697 733
698 nt->transport_link = NTB_LINK_UP; 734 nt->transport_link = NTB_LINK_UP;
699 735
@@ -708,6 +744,9 @@ static void ntb_transport_link_work(struct work_struct *work)
708 744
709 return; 745 return;
710 746
747out1:
748 for (i = 0; i < NTB_NUM_MW; i++)
749 ntb_free_mw(nt, i);
711out: 750out:
712 if (ntb_hw_link_status(ndev)) 751 if (ntb_hw_link_status(ndev))
713 schedule_delayed_work(&nt->link_work, 752 schedule_delayed_work(&nt->link_work,
@@ -780,10 +819,10 @@ static void ntb_transport_init_queue(struct ntb_transport *nt,
780 (qp_num / NTB_NUM_MW * tx_size); 819 (qp_num / NTB_NUM_MW * tx_size);
781 tx_size -= sizeof(struct ntb_rx_info); 820 tx_size -= sizeof(struct ntb_rx_info);
782 821
783 qp->tx_mw = qp->rx_info + sizeof(struct ntb_rx_info); 822 qp->tx_mw = qp->rx_info + 1;
784 qp->tx_max_frame = min(transport_mtu, tx_size); 823 /* Due to housekeeping, there must be atleast 2 buffs */
824 qp->tx_max_frame = min(transport_mtu, tx_size / 2);
785 qp->tx_max_entry = tx_size / qp->tx_max_frame; 825 qp->tx_max_entry = tx_size / qp->tx_max_frame;
786 qp->tx_index = 0;
787 826
788 if (nt->debugfs_dir) { 827 if (nt->debugfs_dir) {
789 char debugfs_name[4]; 828 char debugfs_name[4];
@@ -897,10 +936,7 @@ void ntb_transport_free(void *transport)
897 pdev = ntb_query_pdev(nt->ndev); 936 pdev = ntb_query_pdev(nt->ndev);
898 937
899 for (i = 0; i < NTB_NUM_MW; i++) 938 for (i = 0; i < NTB_NUM_MW; i++)
900 if (nt->mw[i].virt_addr) 939 ntb_free_mw(nt, i);
901 dma_free_coherent(&pdev->dev, nt->mw[i].size,
902 nt->mw[i].virt_addr,
903 nt->mw[i].dma_addr);
904 940
905 kfree(nt->qps); 941 kfree(nt->qps);
906 ntb_unregister_transport(nt->ndev); 942 ntb_unregister_transport(nt->ndev);
@@ -999,11 +1035,16 @@ out:
999static void ntb_transport_rx(unsigned long data) 1035static void ntb_transport_rx(unsigned long data)
1000{ 1036{
1001 struct ntb_transport_qp *qp = (struct ntb_transport_qp *)data; 1037 struct ntb_transport_qp *qp = (struct ntb_transport_qp *)data;
1002 int rc; 1038 int rc, i;
1003 1039
1004 do { 1040 /* Limit the number of packets processed in a single interrupt to
1041 * provide fairness to others
1042 */
1043 for (i = 0; i < qp->rx_max_entry; i++) {
1005 rc = ntb_process_rxc(qp); 1044 rc = ntb_process_rxc(qp);
1006 } while (!rc); 1045 if (rc)
1046 break;
1047 }
1007} 1048}
1008 1049
1009static void ntb_transport_rxc_db(void *data, int db_num) 1050static void ntb_transport_rxc_db(void *data, int db_num)
@@ -1210,12 +1251,14 @@ EXPORT_SYMBOL_GPL(ntb_transport_create_queue);
1210 */ 1251 */
1211void ntb_transport_free_queue(struct ntb_transport_qp *qp) 1252void ntb_transport_free_queue(struct ntb_transport_qp *qp)
1212{ 1253{
1213 struct pci_dev *pdev = ntb_query_pdev(qp->ndev); 1254 struct pci_dev *pdev;
1214 struct ntb_queue_entry *entry; 1255 struct ntb_queue_entry *entry;
1215 1256
1216 if (!qp) 1257 if (!qp)
1217 return; 1258 return;
1218 1259
1260 pdev = ntb_query_pdev(qp->ndev);
1261
1219 cancel_delayed_work_sync(&qp->link_work); 1262 cancel_delayed_work_sync(&qp->link_work);
1220 1263
1221 ntb_unregister_db_callback(qp->ndev, qp->qp_num); 1264 ntb_unregister_db_callback(qp->ndev, qp->qp_num);
@@ -1371,12 +1414,13 @@ EXPORT_SYMBOL_GPL(ntb_transport_link_up);
1371 */ 1414 */
1372void ntb_transport_link_down(struct ntb_transport_qp *qp) 1415void ntb_transport_link_down(struct ntb_transport_qp *qp)
1373{ 1416{
1374 struct pci_dev *pdev = ntb_query_pdev(qp->ndev); 1417 struct pci_dev *pdev;
1375 int rc, val; 1418 int rc, val;
1376 1419
1377 if (!qp) 1420 if (!qp)
1378 return; 1421 return;
1379 1422
1423 pdev = ntb_query_pdev(qp->ndev);
1380 qp->client_ready = NTB_LINK_DOWN; 1424 qp->client_ready = NTB_LINK_DOWN;
1381 1425
1382 rc = ntb_read_local_spad(qp->ndev, QP_LINKS, &val); 1426 rc = ntb_read_local_spad(qp->ndev, QP_LINKS, &val);
@@ -1408,6 +1452,9 @@ EXPORT_SYMBOL_GPL(ntb_transport_link_down);
1408 */ 1452 */
1409bool ntb_transport_link_query(struct ntb_transport_qp *qp) 1453bool ntb_transport_link_query(struct ntb_transport_qp *qp)
1410{ 1454{
1455 if (!qp)
1456 return false;
1457
1411 return qp->qp_link == NTB_LINK_UP; 1458 return qp->qp_link == NTB_LINK_UP;
1412} 1459}
1413EXPORT_SYMBOL_GPL(ntb_transport_link_query); 1460EXPORT_SYMBOL_GPL(ntb_transport_link_query);
@@ -1422,6 +1469,9 @@ EXPORT_SYMBOL_GPL(ntb_transport_link_query);
1422 */ 1469 */
1423unsigned char ntb_transport_qp_num(struct ntb_transport_qp *qp) 1470unsigned char ntb_transport_qp_num(struct ntb_transport_qp *qp)
1424{ 1471{
1472 if (!qp)
1473 return 0;
1474
1425 return qp->qp_num; 1475 return qp->qp_num;
1426} 1476}
1427EXPORT_SYMBOL_GPL(ntb_transport_qp_num); 1477EXPORT_SYMBOL_GPL(ntb_transport_qp_num);
@@ -1436,6 +1486,9 @@ EXPORT_SYMBOL_GPL(ntb_transport_qp_num);
1436 */ 1486 */
1437unsigned int ntb_transport_max_size(struct ntb_transport_qp *qp) 1487unsigned int ntb_transport_max_size(struct ntb_transport_qp *qp)
1438{ 1488{
1489 if (!qp)
1490 return 0;
1491
1439 return qp->tx_max_frame - sizeof(struct ntb_payload_header); 1492 return qp->tx_max_frame - sizeof(struct ntb_payload_header);
1440} 1493}
1441EXPORT_SYMBOL_GPL(ntb_transport_max_size); 1494EXPORT_SYMBOL_GPL(ntb_transport_max_size);