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

[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 15 роки тому
джерело
коміт
ad66465b3c

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

2071
     pseudo_bit_t	pkv[0x00001];          /* PKey Violation Counter Supported */
2071
     pseudo_bit_t	pkv[0x00001];          /* PKey Violation Counter Supported */
2072
     pseudo_bit_t	qkv[0x00001];          /* QKey Violation Coutner Supported */
2072
     pseudo_bit_t	qkv[0x00001];          /* QKey Violation Coutner Supported */
2073
     pseudo_bit_t	vmm[0x00001];          /* Hermon New */
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
     pseudo_bit_t	mw[0x00001];           /* Memory windows supported */
2079
     pseudo_bit_t	mw[0x00001];           /* Memory windows supported */
2076
     pseudo_bit_t	apm[0x00001];          /* Automatic Path Migration Supported */
2080
     pseudo_bit_t	apm[0x00001];          /* Automatic Path Migration Supported */
2077
     pseudo_bit_t	atm[0x00001];          /* Atomic operations supported (atomicity is guaranteed between QPs on this HCA) */
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
 			    0, map, 1, NULL );
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
  * Memory translation table operations
556
  * Memory translation table operations
1664
 	       ( link_up ? "up" : "down" ) );
1674
 	       ( link_up ? "up" : "down" ) );
1665
 
1675
 
1666
 	/* Sanity check */
1676
 	/* Sanity check */
1667
-	if ( port >= HERMON_NUM_PORTS ) {
1677
+	if ( port >= hermon->cap.num_ports ) {
1668
 		DBGC ( hermon, "Hermon %p port %d does not exist!\n",
1678
 		DBGC ( hermon, "Hermon %p port %d does not exist!\n",
1669
 		       hermon, ( port + 1 ) );
1679
 		       hermon, ( port + 1 ) );
1670
 		return;
1680
 		return;
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
  * Initialise Infiniband link
1779
  * Initialise Infiniband link
1740
  *
1780
  *
1744
 static int hermon_open ( struct ib_device *ibdev ) {
1784
 static int hermon_open ( struct ib_device *ibdev ) {
1745
 	struct hermon *hermon = ib_get_drvdata ( ibdev );
1785
 	struct hermon *hermon = ib_get_drvdata ( ibdev );
1746
 	struct hermonprm_init_port init_port;
1786
 	struct hermonprm_init_port init_port;
1787
+	int port_type;
1747
 	int rc;
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
 	memset ( &init_port, 0, sizeof ( init_port ) );
1800
 	memset ( &init_port, 0, sizeof ( init_port ) );
1750
 	MLX_FILL_2 ( &init_port, 0,
1801
 	MLX_FILL_2 ( &init_port, 0,
1751
 		     port_width_cap, 3,
1802
 		     port_width_cap, 3,
2099
 		( 1 << MLX_GET ( &dev_cap, log2_rsvd_mrws ) );
2150
 		( 1 << MLX_GET ( &dev_cap, log2_rsvd_mrws ) );
2100
 	hermon->cap.dmpt_entry_size = MLX_GET ( &dev_cap, d_mpt_entry_sz );
2151
 	hermon->cap.dmpt_entry_size = MLX_GET ( &dev_cap, d_mpt_entry_sz );
2101
 	hermon->cap.reserved_uars = MLX_GET ( &dev_cap, num_rsvd_uars );
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
 	return 0;
2163
 	return 0;
2104
 }
2164
 }
2478
 	struct hermon *hermon;
2538
 	struct hermon *hermon;
2479
 	struct ib_device *ibdev;
2539
 	struct ib_device *ibdev;
2480
 	struct hermonprm_init_hca init_hca;
2540
 	struct hermonprm_init_hca init_hca;
2481
-	int i;
2541
+	unsigned int i;
2482
 	int rc;
2542
 	int rc;
2483
 
2543
 
2484
 	/* Allocate Hermon device */
2544
 	/* Allocate Hermon device */
2489
 	}
2549
 	}
2490
 	pci_set_drvdata ( pci, hermon );
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
 	/* Fix up PCI device */
2552
 	/* Fix up PCI device */
2507
 	adjust_pci_device ( pci );
2553
 	adjust_pci_device ( pci );
2508
 
2554
 
2534
 	if ( ( rc = hermon_get_cap ( hermon ) ) != 0 )
2580
 	if ( ( rc = hermon_get_cap ( hermon ) ) != 0 )
2535
 		goto err_get_cap;
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
 	/* Allocate ICM */
2597
 	/* Allocate ICM */
2538
 	memset ( &init_hca, 0, sizeof ( init_hca ) );
2598
 	memset ( &init_hca, 0, sizeof ( init_hca ) );
2539
 	if ( ( rc = hermon_alloc_icm ( hermon, &init_hca ) ) != 0 )
2599
 	if ( ( rc = hermon_alloc_icm ( hermon, &init_hca ) ) != 0 )
2552
 	/* Set up memory protection */
2612
 	/* Set up memory protection */
2553
 	if ( ( rc = hermon_setup_mpt ( hermon ) ) != 0 )
2613
 	if ( ( rc = hermon_setup_mpt ( hermon ) ) != 0 )
2554
 		goto err_setup_mpt;
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
 		hermon->ibdev[i]->rdma_key = hermon->lkey;
2616
 		hermon->ibdev[i]->rdma_key = hermon->lkey;
2557
 
2617
 
2558
 	/* Set up event queue */
2618
 	/* Set up event queue */
2563
 	if ( ( rc = hermon_configure_special_qps ( hermon ) ) != 0 )
2623
 	if ( ( rc = hermon_configure_special_qps ( hermon ) ) != 0 )
2564
 		goto err_conf_special_qps;
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
 		ib_smc_update ( hermon->ibdev[i], hermon_mad );
2628
 		ib_smc_update ( hermon->ibdev[i], hermon_mad );
2629
+	}
2569
 
2630
 
2570
 	/* Register Infiniband devices */
2631
 	/* Register Infiniband devices */
2571
-	for ( i = 0 ; i < HERMON_NUM_PORTS ; i++ ) {
2632
+	for ( i = 0 ; i < hermon->cap.num_ports ; i++ ) {
2572
 		if ( ( rc = register_ibdev ( hermon->ibdev[i] ) ) != 0 ) {
2633
 		if ( ( rc = register_ibdev ( hermon->ibdev[i] ) ) != 0 ) {
2573
 			DBGC ( hermon, "Hermon %p could not register IB "
2634
 			DBGC ( hermon, "Hermon %p could not register IB "
2574
 			       "device: %s\n", hermon, strerror ( rc ) );
2635
 			       "device: %s\n", hermon, strerror ( rc ) );
2578
 
2639
 
2579
 	return 0;
2640
 	return 0;
2580
 
2641
 
2581
-	i = HERMON_NUM_PORTS;
2642
+	i = hermon->cap.num_ports;
2582
  err_register_ibdev:
2643
  err_register_ibdev:
2583
-	for ( i-- ; i >= 0 ; i-- )
2644
+	for ( i-- ; ( signed int ) i >= 0 ; i-- )
2584
 		unregister_ibdev ( hermon->ibdev[i] );
2645
 		unregister_ibdev ( hermon->ibdev[i] );
2585
  err_conf_special_qps:
2646
  err_conf_special_qps:
2586
 	hermon_destroy_eq ( hermon );
2647
 	hermon_destroy_eq ( hermon );
2590
  err_init_hca:
2651
  err_init_hca:
2591
 	hermon_free_icm ( hermon );
2652
 	hermon_free_icm ( hermon );
2592
  err_alloc_icm:
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
  err_get_cap:
2658
  err_get_cap:
2594
 	hermon_stop_firmware ( hermon );
2659
 	hermon_stop_firmware ( hermon );
2595
  err_start_firmware:
2660
  err_start_firmware:
2597
  err_mailbox_out:
2662
  err_mailbox_out:
2598
 	free_dma ( hermon->mailbox_in, HERMON_MBOX_SIZE );
2663
 	free_dma ( hermon->mailbox_in, HERMON_MBOX_SIZE );
2599
  err_mailbox_in:
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
 	free ( hermon );
2665
 	free ( hermon );
2605
  err_alloc_hermon:
2666
  err_alloc_hermon:
2606
 	return rc;
2667
 	return rc;
2615
 	struct hermon *hermon = pci_get_drvdata ( pci );
2676
 	struct hermon *hermon = pci_get_drvdata ( pci );
2616
 	int i;
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
 		unregister_ibdev ( hermon->ibdev[i] );
2680
 		unregister_ibdev ( hermon->ibdev[i] );
2620
 	hermon_destroy_eq ( hermon );
2681
 	hermon_destroy_eq ( hermon );
2621
 	hermon_cmd_close_hca ( hermon );
2682
 	hermon_cmd_close_hca ( hermon );
2624
 	hermon_stop_firmware ( hermon );
2685
 	hermon_stop_firmware ( hermon );
2625
 	free_dma ( hermon->mailbox_out, HERMON_MBOX_SIZE );
2686
 	free_dma ( hermon->mailbox_out, HERMON_MBOX_SIZE );
2626
 	free_dma ( hermon->mailbox_in, HERMON_MBOX_SIZE );
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
 		ibdev_put ( hermon->ibdev[i] );
2689
 		ibdev_put ( hermon->ibdev[i] );
2629
 	free ( hermon );
2690
 	free ( hermon );
2630
 }
2691
 }

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

21
  */
21
  */
22
 
22
 
23
 /* Ports in existence */
23
 /* Ports in existence */
24
-#define HERMON_NUM_PORTS		2
24
+#define HERMON_MAX_PORTS		2
25
 #define HERMON_PORT_BASE		1
25
 #define HERMON_PORT_BASE		1
26
 
26
 
27
 /* PCI BARs */
27
 /* PCI BARs */
61
 #define HERMON_HCR_READ_MCG		0x0025
61
 #define HERMON_HCR_READ_MCG		0x0025
62
 #define HERMON_HCR_WRITE_MCG		0x0026
62
 #define HERMON_HCR_WRITE_MCG		0x0026
63
 #define HERMON_HCR_MGID_HASH		0x0027
63
 #define HERMON_HCR_MGID_HASH		0x0027
64
+#define HERMON_HCR_SENSE_PORT		0x004d
64
 #define HERMON_HCR_RUN_FW		0x0ff6
65
 #define HERMON_HCR_RUN_FW		0x0ff6
65
 #define HERMON_HCR_DISABLE_LAM		0x0ff7
66
 #define HERMON_HCR_DISABLE_LAM		0x0ff7
66
 #define HERMON_HCR_ENABLE_LAM		0x0ff8
67
 #define HERMON_HCR_ENABLE_LAM		0x0ff8
164
 	struct hermonprm_port_state_change_st data;
165
 	struct hermonprm_port_state_change_st data;
165
 } __attribute__ (( packed ));
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
  * Wrapper structures for hardware datatypes
177
  * Wrapper structures for hardware datatypes
169
  *
178
  *
192
 struct MLX_DECLARE_STRUCT ( hermonprm_query_fw );
201
 struct MLX_DECLARE_STRUCT ( hermonprm_query_fw );
193
 struct MLX_DECLARE_STRUCT ( hermonprm_queue_pair_ee_context_entry );
202
 struct MLX_DECLARE_STRUCT ( hermonprm_queue_pair_ee_context_entry );
194
 struct MLX_DECLARE_STRUCT ( hermonprm_scalar_parameter );
203
 struct MLX_DECLARE_STRUCT ( hermonprm_scalar_parameter );
204
+struct MLX_DECLARE_STRUCT ( hermonprm_sense_port );
195
 struct MLX_DECLARE_STRUCT ( hermonprm_send_db_register );
205
 struct MLX_DECLARE_STRUCT ( hermonprm_send_db_register );
196
 struct MLX_DECLARE_STRUCT ( hermonprm_ud_address_vector );
206
 struct MLX_DECLARE_STRUCT ( hermonprm_ud_address_vector );
197
 struct MLX_DECLARE_STRUCT ( hermonprm_virtual_physical_mapping );
207
 struct MLX_DECLARE_STRUCT ( hermonprm_virtual_physical_mapping );
296
 	size_t dmpt_entry_size;
306
 	size_t dmpt_entry_size;
297
 	/** Number of reserved UARs */
307
 	/** Number of reserved UARs */
298
 	unsigned int reserved_uars;
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
 /** Number of cMPT entries of each type */
315
 /** Number of cMPT entries of each type */
523
 	unsigned long qpn_base;
537
 	unsigned long qpn_base;
524
 
538
 
525
 	/** Infiniband devices */
539
 	/** Infiniband devices */
526
-	struct ib_device *ibdev[HERMON_NUM_PORTS];
540
+	struct ib_device *ibdev[HERMON_MAX_PORTS];
527
 };
541
 };
528
 
542
 
529
 /** Global protection domain */
543
 /** Global protection domain */

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