Переглянути джерело

[hermon] Add support for multiple ports and detecting non-IB ports

Originally-fixed-by: Itay Gazit <itaygazit@gmail.com>
tags/v0.9.8
Michael Brown 14 роки тому
джерело
коміт
ad66465b3c

+ 5
- 1
src/drivers/infiniband/MT25408_PRM.h Переглянути файл

@@ -2071,7 +2071,11 @@ struct hermonprm_query_dev_cap_st {	/* Little Endian */
2071 2071
     pseudo_bit_t	pkv[0x00001];          /* PKey Violation Counter Supported */
2072 2072
     pseudo_bit_t	qkv[0x00001];          /* QKey Violation Coutner Supported */
2073 2073
     pseudo_bit_t	vmm[0x00001];          /* Hermon New */
2074
-    pseudo_bit_t	reserved27[0x00005];
2074
+    pseudo_bit_t	fcoe[0x00001];
2075
+    pseudo_bit_t	dpdp[0x00001];	       /* Dual Port Different Protocols */
2076
+    pseudo_bit_t	raw_ethertype[0x00001];
2077
+    pseudo_bit_t	raw_ipv6[0x00001];
2078
+    pseudo_bit_t	blh[0x00001];
2075 2079
     pseudo_bit_t	mw[0x00001];           /* Memory windows supported */
2076 2080
     pseudo_bit_t	apm[0x00001];          /* Automatic Path Migration Supported */
2077 2081
     pseudo_bit_t	atm[0x00001];          /* Atomic operations supported (atomicity is guaranteed between QPs on this HCA) */

+ 89
- 28
src/drivers/infiniband/hermon.c Переглянути файл

@@ -541,6 +541,16 @@ hermon_cmd_map_fa ( struct hermon *hermon,
541 541
 			    0, map, 1, NULL );
542 542
 }
543 543
 
544
+static inline int
545
+hermon_cmd_sense_port ( struct hermon *hermon, unsigned int port,
546
+			struct hermonprm_sense_port *port_type ) {
547
+	return hermon_cmd ( hermon,
548
+                            HERMON_HCR_OUT_CMD ( HERMON_HCR_SENSE_PORT,
549
+                                                 1, sizeof ( *port_type ) ),
550
+                            0, NULL, port, port_type );
551
+}
552
+
553
+
544 554
 /***************************************************************************
545 555
  *
546 556
  * Memory translation table operations
@@ -1664,7 +1674,7 @@ static void hermon_event_port_state_change ( struct hermon *hermon,
1664 1674
 	       ( link_up ? "up" : "down" ) );
1665 1675
 
1666 1676
 	/* Sanity check */
1667
-	if ( port >= HERMON_NUM_PORTS ) {
1677
+	if ( port >= hermon->cap.num_ports ) {
1668 1678
 		DBGC ( hermon, "Hermon %p port %d does not exist!\n",
1669 1679
 		       hermon, ( port + 1 ) );
1670 1680
 		return;
@@ -1735,6 +1745,36 @@ static void hermon_poll_eq ( struct ib_device *ibdev ) {
1735 1745
  ***************************************************************************
1736 1746
  */
1737 1747
 
1748
+/**
1749
+ * Sense port type
1750
+ *
1751
+ * @v ibdev		Infiniband device
1752
+ * @ret port_type	Port type, or negative error
1753
+ */
1754
+static int hermon_sense_port_type ( struct ib_device *ibdev ) {
1755
+	struct hermon *hermon = ib_get_drvdata ( ibdev );
1756
+	struct hermonprm_sense_port sense_port;
1757
+	int port_type;
1758
+	int rc;
1759
+
1760
+	/* If DPDP is not supported, always assume Infiniband */
1761
+	if ( ! hermon->cap.dpdp )
1762
+		return HERMON_PORT_TYPE_IB;
1763
+
1764
+	/* Sense the port type */
1765
+	if ( ( rc = hermon_cmd_sense_port ( hermon, ibdev->port,
1766
+					    &sense_port ) ) != 0 ) {
1767
+		DBGC ( hermon, "Hermon %p port %d sense failed: %s\n",
1768
+		       hermon, ibdev->port, strerror ( rc ) );
1769
+		return rc;
1770
+	}
1771
+	port_type = MLX_GET ( &sense_port, port_type );
1772
+
1773
+	DBGC ( hermon, "Hermon %p port %d type %d\n",
1774
+	       hermon, ibdev->port, port_type );
1775
+	return port_type;
1776
+}
1777
+
1738 1778
 /**
1739 1779
  * Initialise Infiniband link
1740 1780
  *
@@ -1744,8 +1784,19 @@ static void hermon_poll_eq ( struct ib_device *ibdev ) {
1744 1784
 static int hermon_open ( struct ib_device *ibdev ) {
1745 1785
 	struct hermon *hermon = ib_get_drvdata ( ibdev );
1746 1786
 	struct hermonprm_init_port init_port;
1787
+	int port_type;
1747 1788
 	int rc;
1748 1789
 
1790
+	/* Check we are connected to an Infiniband network */
1791
+	if ( ( rc = port_type = hermon_sense_port_type ( ibdev ) ) < 0 )
1792
+		return rc;
1793
+	if ( port_type != HERMON_PORT_TYPE_IB ) {
1794
+		DBGC ( hermon, "Hermon %p port %d not connected to an "
1795
+		       "Infiniband network", hermon, ibdev->port );
1796
+		return -ENOTCONN;
1797
+        }
1798
+
1799
+	/* Init Port */
1749 1800
 	memset ( &init_port, 0, sizeof ( init_port ) );
1750 1801
 	MLX_FILL_2 ( &init_port, 0,
1751 1802
 		     port_width_cap, 3,
@@ -2099,6 +2150,15 @@ static int hermon_get_cap ( struct hermon *hermon ) {
2099 2150
 		( 1 << MLX_GET ( &dev_cap, log2_rsvd_mrws ) );
2100 2151
 	hermon->cap.dmpt_entry_size = MLX_GET ( &dev_cap, d_mpt_entry_sz );
2101 2152
 	hermon->cap.reserved_uars = MLX_GET ( &dev_cap, num_rsvd_uars );
2153
+	hermon->cap.num_ports = MLX_GET ( &dev_cap, num_ports );
2154
+	hermon->cap.dpdp = MLX_GET ( &dev_cap, dpdp );
2155
+
2156
+	/* Sanity check */
2157
+	if ( hermon->cap.num_ports > HERMON_MAX_PORTS ) {
2158
+		DBGC ( hermon, "Hermon %p has %d ports (only %d supported)\n",
2159
+		       hermon, hermon->cap.num_ports, HERMON_MAX_PORTS );
2160
+		hermon->cap.num_ports = HERMON_MAX_PORTS;
2161
+	}
2102 2162
 
2103 2163
 	return 0;
2104 2164
 }
@@ -2478,7 +2538,7 @@ static int hermon_probe ( struct pci_device *pci,
2478 2538
 	struct hermon *hermon;
2479 2539
 	struct ib_device *ibdev;
2480 2540
 	struct hermonprm_init_hca init_hca;
2481
-	int i;
2541
+	unsigned int i;
2482 2542
 	int rc;
2483 2543
 
2484 2544
 	/* Allocate Hermon device */
@@ -2489,20 +2549,6 @@ static int hermon_probe ( struct pci_device *pci,
2489 2549
 	}
2490 2550
 	pci_set_drvdata ( pci, hermon );
2491 2551
 
2492
-	/* Allocate Infiniband devices */
2493
-	for ( i = 0 ; i < HERMON_NUM_PORTS ; i++ ) {
2494
-	        ibdev = alloc_ibdev ( 0 );
2495
-		if ( ! ibdev ) {
2496
-			rc = -ENOMEM;
2497
-			goto err_alloc_ibdev;
2498
-		}
2499
-		hermon->ibdev[i] = ibdev;
2500
-		ibdev->op = &hermon_ib_operations;
2501
-		ibdev->dev = &pci->dev;
2502
-		ibdev->port = ( HERMON_PORT_BASE + i );
2503
-		ib_set_drvdata ( ibdev, hermon );
2504
-	}
2505
-
2506 2552
 	/* Fix up PCI device */
2507 2553
 	adjust_pci_device ( pci );
2508 2554
 
@@ -2534,6 +2580,20 @@ static int hermon_probe ( struct pci_device *pci,
2534 2580
 	if ( ( rc = hermon_get_cap ( hermon ) ) != 0 )
2535 2581
 		goto err_get_cap;
2536 2582
 
2583
+	/* Allocate Infiniband devices */
2584
+	for ( i = 0 ; i < hermon->cap.num_ports ; i++ ) {
2585
+	        ibdev = alloc_ibdev ( 0 );
2586
+		if ( ! ibdev ) {
2587
+			rc = -ENOMEM;
2588
+			goto err_alloc_ibdev;
2589
+		}
2590
+		hermon->ibdev[i] = ibdev;
2591
+		ibdev->op = &hermon_ib_operations;
2592
+		ibdev->dev = &pci->dev;
2593
+		ibdev->port = ( HERMON_PORT_BASE + i );
2594
+		ib_set_drvdata ( ibdev, hermon );
2595
+	}
2596
+
2537 2597
 	/* Allocate ICM */
2538 2598
 	memset ( &init_hca, 0, sizeof ( init_hca ) );
2539 2599
 	if ( ( rc = hermon_alloc_icm ( hermon, &init_hca ) ) != 0 )
@@ -2552,7 +2612,7 @@ static int hermon_probe ( struct pci_device *pci,
2552 2612
 	/* Set up memory protection */
2553 2613
 	if ( ( rc = hermon_setup_mpt ( hermon ) ) != 0 )
2554 2614
 		goto err_setup_mpt;
2555
-	for ( i = 0 ; i < HERMON_NUM_PORTS ; i++ )
2615
+	for ( i = 0 ; i < hermon->cap.num_ports ; i++ )
2556 2616
 		hermon->ibdev[i]->rdma_key = hermon->lkey;
2557 2617
 
2558 2618
 	/* Set up event queue */
@@ -2563,12 +2623,13 @@ static int hermon_probe ( struct pci_device *pci,
2563 2623
 	if ( ( rc = hermon_configure_special_qps ( hermon ) ) != 0 )
2564 2624
 		goto err_conf_special_qps;
2565 2625
 
2566
-	/* Update MAD parameters */
2567
-	for ( i = 0 ; i < HERMON_NUM_PORTS ; i++ )
2626
+	/* Update IPoIB MAC address */
2627
+	for ( i = 0 ; i < hermon->cap.num_ports ; i++ ) {
2568 2628
 		ib_smc_update ( hermon->ibdev[i], hermon_mad );
2629
+	}
2569 2630
 
2570 2631
 	/* Register Infiniband devices */
2571
-	for ( i = 0 ; i < HERMON_NUM_PORTS ; i++ ) {
2632
+	for ( i = 0 ; i < hermon->cap.num_ports ; i++ ) {
2572 2633
 		if ( ( rc = register_ibdev ( hermon->ibdev[i] ) ) != 0 ) {
2573 2634
 			DBGC ( hermon, "Hermon %p could not register IB "
2574 2635
 			       "device: %s\n", hermon, strerror ( rc ) );
@@ -2578,9 +2639,9 @@ static int hermon_probe ( struct pci_device *pci,
2578 2639
 
2579 2640
 	return 0;
2580 2641
 
2581
-	i = HERMON_NUM_PORTS;
2642
+	i = hermon->cap.num_ports;
2582 2643
  err_register_ibdev:
2583
-	for ( i-- ; i >= 0 ; i-- )
2644
+	for ( i-- ; ( signed int ) i >= 0 ; i-- )
2584 2645
 		unregister_ibdev ( hermon->ibdev[i] );
2585 2646
  err_conf_special_qps:
2586 2647
 	hermon_destroy_eq ( hermon );
@@ -2590,6 +2651,10 @@ static int hermon_probe ( struct pci_device *pci,
2590 2651
  err_init_hca:
2591 2652
 	hermon_free_icm ( hermon );
2592 2653
  err_alloc_icm:
2654
+	i = hermon->cap.num_ports;
2655
+ err_alloc_ibdev:
2656
+	for ( i-- ; ( signed int ) i >= 0 ; i-- )
2657
+		ibdev_put ( hermon->ibdev[i] );
2593 2658
  err_get_cap:
2594 2659
 	hermon_stop_firmware ( hermon );
2595 2660
  err_start_firmware:
@@ -2597,10 +2662,6 @@ static int hermon_probe ( struct pci_device *pci,
2597 2662
  err_mailbox_out:
2598 2663
 	free_dma ( hermon->mailbox_in, HERMON_MBOX_SIZE );
2599 2664
  err_mailbox_in:
2600
-	i = HERMON_NUM_PORTS;
2601
- err_alloc_ibdev:
2602
-	for ( i-- ; i >= 0 ; i-- )
2603
-		ibdev_put ( hermon->ibdev[i] );
2604 2665
 	free ( hermon );
2605 2666
  err_alloc_hermon:
2606 2667
 	return rc;
@@ -2615,7 +2676,7 @@ static void hermon_remove ( struct pci_device *pci ) {
2615 2676
 	struct hermon *hermon = pci_get_drvdata ( pci );
2616 2677
 	int i;
2617 2678
 
2618
-	for ( i = ( HERMON_NUM_PORTS - 1 ) ; i >= 0 ; i-- )
2679
+	for ( i = ( hermon->cap.num_ports - 1 ) ; i >= 0 ; i-- )
2619 2680
 		unregister_ibdev ( hermon->ibdev[i] );
2620 2681
 	hermon_destroy_eq ( hermon );
2621 2682
 	hermon_cmd_close_hca ( hermon );
@@ -2624,7 +2685,7 @@ static void hermon_remove ( struct pci_device *pci ) {
2624 2685
 	hermon_stop_firmware ( hermon );
2625 2686
 	free_dma ( hermon->mailbox_out, HERMON_MBOX_SIZE );
2626 2687
 	free_dma ( hermon->mailbox_in, HERMON_MBOX_SIZE );
2627
-	for ( i = ( HERMON_NUM_PORTS - 1 ) ; i >= 0 ; i-- )
2688
+	for ( i = ( hermon->cap.num_ports - 1 ) ; i >= 0 ; i-- )
2628 2689
 		ibdev_put ( hermon->ibdev[i] );
2629 2690
 	free ( hermon );
2630 2691
 }

+ 16
- 2
src/drivers/infiniband/hermon.h Переглянути файл

@@ -21,7 +21,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
21 21
  */
22 22
 
23 23
 /* Ports in existence */
24
-#define HERMON_NUM_PORTS		2
24
+#define HERMON_MAX_PORTS		2
25 25
 #define HERMON_PORT_BASE		1
26 26
 
27 27
 /* PCI BARs */
@@ -61,6 +61,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
61 61
 #define HERMON_HCR_READ_MCG		0x0025
62 62
 #define HERMON_HCR_WRITE_MCG		0x0026
63 63
 #define HERMON_HCR_MGID_HASH		0x0027
64
+#define HERMON_HCR_SENSE_PORT		0x004d
64 65
 #define HERMON_HCR_RUN_FW		0x0ff6
65 66
 #define HERMON_HCR_DISABLE_LAM		0x0ff7
66 67
 #define HERMON_HCR_ENABLE_LAM		0x0ff8
@@ -164,6 +165,14 @@ struct hermonprm_port_state_change_event_st {
164 165
 	struct hermonprm_port_state_change_st data;
165 166
 } __attribute__ (( packed ));
166 167
 
168
+/** Hermon sense port */
169
+struct hermonprm_sense_port_st {
170
+	pseudo_bit_t port_type[0x00020];
171
+/* -------------- */
172
+	pseudo_bit_t reserved[0x00020];
173
+};
174
+#define HERMON_PORT_TYPE_IB		1
175
+
167 176
 /*
168 177
  * Wrapper structures for hardware datatypes
169 178
  *
@@ -192,6 +201,7 @@ struct MLX_DECLARE_STRUCT ( hermonprm_query_dev_cap );
192 201
 struct MLX_DECLARE_STRUCT ( hermonprm_query_fw );
193 202
 struct MLX_DECLARE_STRUCT ( hermonprm_queue_pair_ee_context_entry );
194 203
 struct MLX_DECLARE_STRUCT ( hermonprm_scalar_parameter );
204
+struct MLX_DECLARE_STRUCT ( hermonprm_sense_port );
195 205
 struct MLX_DECLARE_STRUCT ( hermonprm_send_db_register );
196 206
 struct MLX_DECLARE_STRUCT ( hermonprm_ud_address_vector );
197 207
 struct MLX_DECLARE_STRUCT ( hermonprm_virtual_physical_mapping );
@@ -296,6 +306,10 @@ struct hermon_dev_cap {
296 306
 	size_t dmpt_entry_size;
297 307
 	/** Number of reserved UARs */
298 308
 	unsigned int reserved_uars;
309
+	/** Number of ports */
310
+	unsigned int num_ports;
311
+	/** Dual-port different protocol */
312
+	int dpdp;
299 313
 };
300 314
 
301 315
 /** Number of cMPT entries of each type */
@@ -523,7 +537,7 @@ struct hermon {
523 537
 	unsigned long qpn_base;
524 538
 
525 539
 	/** Infiniband devices */
526
-	struct ib_device *ibdev[HERMON_NUM_PORTS];
540
+	struct ib_device *ibdev[HERMON_MAX_PORTS];
527 541
 };
528 542
 
529 543
 /** Global protection domain */

Завантаження…
Відмінити
Зберегти