|
@@ -1892,195 +1892,6 @@ static void arbel_poll_eq ( struct ib_device *ibdev ) {
|
1892
|
1892
|
}
|
1893
|
1893
|
}
|
1894
|
1894
|
|
1895
|
|
-/***************************************************************************
|
1896
|
|
- *
|
1897
|
|
- * Infiniband link-layer operations
|
1898
|
|
- *
|
1899
|
|
- ***************************************************************************
|
1900
|
|
- */
|
1901
|
|
-
|
1902
|
|
-/**
|
1903
|
|
- * Initialise Infiniband link
|
1904
|
|
- *
|
1905
|
|
- * @v ibdev Infiniband device
|
1906
|
|
- * @ret rc Return status code
|
1907
|
|
- */
|
1908
|
|
-static int arbel_open ( struct ib_device *ibdev ) {
|
1909
|
|
- struct arbel *arbel = ib_get_drvdata ( ibdev );
|
1910
|
|
- struct arbelprm_init_ib init_ib;
|
1911
|
|
- int rc;
|
1912
|
|
-
|
1913
|
|
- memset ( &init_ib, 0, sizeof ( init_ib ) );
|
1914
|
|
- MLX_FILL_3 ( &init_ib, 0,
|
1915
|
|
- mtu_cap, ARBEL_MTU_2048,
|
1916
|
|
- port_width_cap, 3,
|
1917
|
|
- vl_cap, 1 );
|
1918
|
|
- MLX_FILL_1 ( &init_ib, 1, max_gid, 1 );
|
1919
|
|
- MLX_FILL_1 ( &init_ib, 2, max_pkey, 64 );
|
1920
|
|
- if ( ( rc = arbel_cmd_init_ib ( arbel, ibdev->port,
|
1921
|
|
- &init_ib ) ) != 0 ) {
|
1922
|
|
- DBGC ( arbel, "Arbel %p port %d could not intialise IB: %s\n",
|
1923
|
|
- arbel, ibdev->port, strerror ( rc ) );
|
1924
|
|
- return rc;
|
1925
|
|
- }
|
1926
|
|
-
|
1927
|
|
- /* Update MAD parameters */
|
1928
|
|
- ib_smc_update ( ibdev, arbel_mad );
|
1929
|
|
-
|
1930
|
|
- return 0;
|
1931
|
|
-}
|
1932
|
|
-
|
1933
|
|
-/**
|
1934
|
|
- * Close Infiniband link
|
1935
|
|
- *
|
1936
|
|
- * @v ibdev Infiniband device
|
1937
|
|
- */
|
1938
|
|
-static void arbel_close ( struct ib_device *ibdev ) {
|
1939
|
|
- struct arbel *arbel = ib_get_drvdata ( ibdev );
|
1940
|
|
- int rc;
|
1941
|
|
-
|
1942
|
|
- if ( ( rc = arbel_cmd_close_ib ( arbel, ibdev->port ) ) != 0 ) {
|
1943
|
|
- DBGC ( arbel, "Arbel %p port %d could not close IB: %s\n",
|
1944
|
|
- arbel, ibdev->port, strerror ( rc ) );
|
1945
|
|
- /* Nothing we can do about this */
|
1946
|
|
- }
|
1947
|
|
-}
|
1948
|
|
-
|
1949
|
|
-/**
|
1950
|
|
- * Inform embedded subnet management agent of a received MAD
|
1951
|
|
- *
|
1952
|
|
- * @v ibdev Infiniband device
|
1953
|
|
- * @v mad MAD
|
1954
|
|
- * @ret rc Return status code
|
1955
|
|
- */
|
1956
|
|
-static int arbel_inform_sma ( struct ib_device *ibdev, union ib_mad *mad ) {
|
1957
|
|
- int rc;
|
1958
|
|
-
|
1959
|
|
- /* Send the MAD to the embedded SMA */
|
1960
|
|
- if ( ( rc = arbel_mad ( ibdev, mad ) ) != 0 )
|
1961
|
|
- return rc;
|
1962
|
|
-
|
1963
|
|
- /* Update parameters held in software */
|
1964
|
|
- ib_smc_update ( ibdev, arbel_mad );
|
1965
|
|
-
|
1966
|
|
- return 0;
|
1967
|
|
-}
|
1968
|
|
-
|
1969
|
|
-/***************************************************************************
|
1970
|
|
- *
|
1971
|
|
- * Multicast group operations
|
1972
|
|
- *
|
1973
|
|
- ***************************************************************************
|
1974
|
|
- */
|
1975
|
|
-
|
1976
|
|
-/**
|
1977
|
|
- * Attach to multicast group
|
1978
|
|
- *
|
1979
|
|
- * @v ibdev Infiniband device
|
1980
|
|
- * @v qp Queue pair
|
1981
|
|
- * @v gid Multicast GID
|
1982
|
|
- * @ret rc Return status code
|
1983
|
|
- */
|
1984
|
|
-static int arbel_mcast_attach ( struct ib_device *ibdev,
|
1985
|
|
- struct ib_queue_pair *qp,
|
1986
|
|
- union ib_gid *gid ) {
|
1987
|
|
- struct arbel *arbel = ib_get_drvdata ( ibdev );
|
1988
|
|
- struct arbelprm_mgm_hash hash;
|
1989
|
|
- struct arbelprm_mgm_entry mgm;
|
1990
|
|
- unsigned int index;
|
1991
|
|
- int rc;
|
1992
|
|
-
|
1993
|
|
- /* Generate hash table index */
|
1994
|
|
- if ( ( rc = arbel_cmd_mgid_hash ( arbel, gid, &hash ) ) != 0 ) {
|
1995
|
|
- DBGC ( arbel, "Arbel %p could not hash GID: %s\n",
|
1996
|
|
- arbel, strerror ( rc ) );
|
1997
|
|
- return rc;
|
1998
|
|
- }
|
1999
|
|
- index = MLX_GET ( &hash, hash );
|
2000
|
|
-
|
2001
|
|
- /* Check for existing hash table entry */
|
2002
|
|
- if ( ( rc = arbel_cmd_read_mgm ( arbel, index, &mgm ) ) != 0 ) {
|
2003
|
|
- DBGC ( arbel, "Arbel %p could not read MGM %#x: %s\n",
|
2004
|
|
- arbel, index, strerror ( rc ) );
|
2005
|
|
- return rc;
|
2006
|
|
- }
|
2007
|
|
- if ( MLX_GET ( &mgm, mgmqp_0.qi ) != 0 ) {
|
2008
|
|
- /* FIXME: this implementation allows only a single QP
|
2009
|
|
- * per multicast group, and doesn't handle hash
|
2010
|
|
- * collisions. Sufficient for IPoIB but may need to
|
2011
|
|
- * be extended in future.
|
2012
|
|
- */
|
2013
|
|
- DBGC ( arbel, "Arbel %p MGID index %#x already in use\n",
|
2014
|
|
- arbel, index );
|
2015
|
|
- return -EBUSY;
|
2016
|
|
- }
|
2017
|
|
-
|
2018
|
|
- /* Update hash table entry */
|
2019
|
|
- MLX_FILL_2 ( &mgm, 8,
|
2020
|
|
- mgmqp_0.qpn_i, qp->qpn,
|
2021
|
|
- mgmqp_0.qi, 1 );
|
2022
|
|
- memcpy ( &mgm.u.dwords[4], gid, sizeof ( *gid ) );
|
2023
|
|
- if ( ( rc = arbel_cmd_write_mgm ( arbel, index, &mgm ) ) != 0 ) {
|
2024
|
|
- DBGC ( arbel, "Arbel %p could not write MGM %#x: %s\n",
|
2025
|
|
- arbel, index, strerror ( rc ) );
|
2026
|
|
- return rc;
|
2027
|
|
- }
|
2028
|
|
-
|
2029
|
|
- return 0;
|
2030
|
|
-}
|
2031
|
|
-
|
2032
|
|
-/**
|
2033
|
|
- * Detach from multicast group
|
2034
|
|
- *
|
2035
|
|
- * @v ibdev Infiniband device
|
2036
|
|
- * @v qp Queue pair
|
2037
|
|
- * @v gid Multicast GID
|
2038
|
|
- */
|
2039
|
|
-static void arbel_mcast_detach ( struct ib_device *ibdev,
|
2040
|
|
- struct ib_queue_pair *qp __unused,
|
2041
|
|
- union ib_gid *gid ) {
|
2042
|
|
- struct arbel *arbel = ib_get_drvdata ( ibdev );
|
2043
|
|
- struct arbelprm_mgm_hash hash;
|
2044
|
|
- struct arbelprm_mgm_entry mgm;
|
2045
|
|
- unsigned int index;
|
2046
|
|
- int rc;
|
2047
|
|
-
|
2048
|
|
- /* Generate hash table index */
|
2049
|
|
- if ( ( rc = arbel_cmd_mgid_hash ( arbel, gid, &hash ) ) != 0 ) {
|
2050
|
|
- DBGC ( arbel, "Arbel %p could not hash GID: %s\n",
|
2051
|
|
- arbel, strerror ( rc ) );
|
2052
|
|
- return;
|
2053
|
|
- }
|
2054
|
|
- index = MLX_GET ( &hash, hash );
|
2055
|
|
-
|
2056
|
|
- /* Clear hash table entry */
|
2057
|
|
- memset ( &mgm, 0, sizeof ( mgm ) );
|
2058
|
|
- if ( ( rc = arbel_cmd_write_mgm ( arbel, index, &mgm ) ) != 0 ) {
|
2059
|
|
- DBGC ( arbel, "Arbel %p could not write MGM %#x: %s\n",
|
2060
|
|
- arbel, index, strerror ( rc ) );
|
2061
|
|
- return;
|
2062
|
|
- }
|
2063
|
|
-}
|
2064
|
|
-
|
2065
|
|
-/** Arbel Infiniband operations */
|
2066
|
|
-static struct ib_device_operations arbel_ib_operations = {
|
2067
|
|
- .create_cq = arbel_create_cq,
|
2068
|
|
- .destroy_cq = arbel_destroy_cq,
|
2069
|
|
- .create_qp = arbel_create_qp,
|
2070
|
|
- .modify_qp = arbel_modify_qp,
|
2071
|
|
- .destroy_qp = arbel_destroy_qp,
|
2072
|
|
- .post_send = arbel_post_send,
|
2073
|
|
- .post_recv = arbel_post_recv,
|
2074
|
|
- .poll_cq = arbel_poll_cq,
|
2075
|
|
- .poll_eq = arbel_poll_eq,
|
2076
|
|
- .open = arbel_open,
|
2077
|
|
- .close = arbel_close,
|
2078
|
|
- .mcast_attach = arbel_mcast_attach,
|
2079
|
|
- .mcast_detach = arbel_mcast_detach,
|
2080
|
|
- .set_port_info = arbel_inform_sma,
|
2081
|
|
- .set_pkey_table = arbel_inform_sma,
|
2082
|
|
-};
|
2083
|
|
-
|
2084
|
1895
|
/***************************************************************************
|
2085
|
1896
|
*
|
2086
|
1897
|
* Firmware control
|
|
@@ -2678,7 +2489,7 @@ static void arbel_free_icm ( struct arbel *arbel ) {
|
2678
|
2489
|
|
2679
|
2490
|
/***************************************************************************
|
2680
|
2491
|
*
|
2681
|
|
- * PCI interface
|
|
2492
|
+ * Initialisation
|
2682
|
2493
|
*
|
2683
|
2494
|
***************************************************************************
|
2684
|
2495
|
*/
|
|
@@ -2761,6 +2572,202 @@ static int arbel_configure_special_qps ( struct arbel *arbel ) {
|
2761
|
2572
|
return 0;
|
2762
|
2573
|
}
|
2763
|
2574
|
|
|
2575
|
+/***************************************************************************
|
|
2576
|
+ *
|
|
2577
|
+ * Infiniband link-layer operations
|
|
2578
|
+ *
|
|
2579
|
+ ***************************************************************************
|
|
2580
|
+ */
|
|
2581
|
+
|
|
2582
|
+/**
|
|
2583
|
+ * Initialise Infiniband link
|
|
2584
|
+ *
|
|
2585
|
+ * @v ibdev Infiniband device
|
|
2586
|
+ * @ret rc Return status code
|
|
2587
|
+ */
|
|
2588
|
+static int arbel_open ( struct ib_device *ibdev ) {
|
|
2589
|
+ struct arbel *arbel = ib_get_drvdata ( ibdev );
|
|
2590
|
+ struct arbelprm_init_ib init_ib;
|
|
2591
|
+ int rc;
|
|
2592
|
+
|
|
2593
|
+ memset ( &init_ib, 0, sizeof ( init_ib ) );
|
|
2594
|
+ MLX_FILL_3 ( &init_ib, 0,
|
|
2595
|
+ mtu_cap, ARBEL_MTU_2048,
|
|
2596
|
+ port_width_cap, 3,
|
|
2597
|
+ vl_cap, 1 );
|
|
2598
|
+ MLX_FILL_1 ( &init_ib, 1, max_gid, 1 );
|
|
2599
|
+ MLX_FILL_1 ( &init_ib, 2, max_pkey, 64 );
|
|
2600
|
+ if ( ( rc = arbel_cmd_init_ib ( arbel, ibdev->port,
|
|
2601
|
+ &init_ib ) ) != 0 ) {
|
|
2602
|
+ DBGC ( arbel, "Arbel %p port %d could not intialise IB: %s\n",
|
|
2603
|
+ arbel, ibdev->port, strerror ( rc ) );
|
|
2604
|
+ return rc;
|
|
2605
|
+ }
|
|
2606
|
+
|
|
2607
|
+ /* Update MAD parameters */
|
|
2608
|
+ ib_smc_update ( ibdev, arbel_mad );
|
|
2609
|
+
|
|
2610
|
+ return 0;
|
|
2611
|
+}
|
|
2612
|
+
|
|
2613
|
+/**
|
|
2614
|
+ * Close Infiniband link
|
|
2615
|
+ *
|
|
2616
|
+ * @v ibdev Infiniband device
|
|
2617
|
+ */
|
|
2618
|
+static void arbel_close ( struct ib_device *ibdev ) {
|
|
2619
|
+ struct arbel *arbel = ib_get_drvdata ( ibdev );
|
|
2620
|
+ int rc;
|
|
2621
|
+
|
|
2622
|
+ if ( ( rc = arbel_cmd_close_ib ( arbel, ibdev->port ) ) != 0 ) {
|
|
2623
|
+ DBGC ( arbel, "Arbel %p port %d could not close IB: %s\n",
|
|
2624
|
+ arbel, ibdev->port, strerror ( rc ) );
|
|
2625
|
+ /* Nothing we can do about this */
|
|
2626
|
+ }
|
|
2627
|
+}
|
|
2628
|
+
|
|
2629
|
+/**
|
|
2630
|
+ * Inform embedded subnet management agent of a received MAD
|
|
2631
|
+ *
|
|
2632
|
+ * @v ibdev Infiniband device
|
|
2633
|
+ * @v mad MAD
|
|
2634
|
+ * @ret rc Return status code
|
|
2635
|
+ */
|
|
2636
|
+static int arbel_inform_sma ( struct ib_device *ibdev, union ib_mad *mad ) {
|
|
2637
|
+ int rc;
|
|
2638
|
+
|
|
2639
|
+ /* Send the MAD to the embedded SMA */
|
|
2640
|
+ if ( ( rc = arbel_mad ( ibdev, mad ) ) != 0 )
|
|
2641
|
+ return rc;
|
|
2642
|
+
|
|
2643
|
+ /* Update parameters held in software */
|
|
2644
|
+ ib_smc_update ( ibdev, arbel_mad );
|
|
2645
|
+
|
|
2646
|
+ return 0;
|
|
2647
|
+}
|
|
2648
|
+
|
|
2649
|
+/***************************************************************************
|
|
2650
|
+ *
|
|
2651
|
+ * Multicast group operations
|
|
2652
|
+ *
|
|
2653
|
+ ***************************************************************************
|
|
2654
|
+ */
|
|
2655
|
+
|
|
2656
|
+/**
|
|
2657
|
+ * Attach to multicast group
|
|
2658
|
+ *
|
|
2659
|
+ * @v ibdev Infiniband device
|
|
2660
|
+ * @v qp Queue pair
|
|
2661
|
+ * @v gid Multicast GID
|
|
2662
|
+ * @ret rc Return status code
|
|
2663
|
+ */
|
|
2664
|
+static int arbel_mcast_attach ( struct ib_device *ibdev,
|
|
2665
|
+ struct ib_queue_pair *qp,
|
|
2666
|
+ union ib_gid *gid ) {
|
|
2667
|
+ struct arbel *arbel = ib_get_drvdata ( ibdev );
|
|
2668
|
+ struct arbelprm_mgm_hash hash;
|
|
2669
|
+ struct arbelprm_mgm_entry mgm;
|
|
2670
|
+ unsigned int index;
|
|
2671
|
+ int rc;
|
|
2672
|
+
|
|
2673
|
+ /* Generate hash table index */
|
|
2674
|
+ if ( ( rc = arbel_cmd_mgid_hash ( arbel, gid, &hash ) ) != 0 ) {
|
|
2675
|
+ DBGC ( arbel, "Arbel %p could not hash GID: %s\n",
|
|
2676
|
+ arbel, strerror ( rc ) );
|
|
2677
|
+ return rc;
|
|
2678
|
+ }
|
|
2679
|
+ index = MLX_GET ( &hash, hash );
|
|
2680
|
+
|
|
2681
|
+ /* Check for existing hash table entry */
|
|
2682
|
+ if ( ( rc = arbel_cmd_read_mgm ( arbel, index, &mgm ) ) != 0 ) {
|
|
2683
|
+ DBGC ( arbel, "Arbel %p could not read MGM %#x: %s\n",
|
|
2684
|
+ arbel, index, strerror ( rc ) );
|
|
2685
|
+ return rc;
|
|
2686
|
+ }
|
|
2687
|
+ if ( MLX_GET ( &mgm, mgmqp_0.qi ) != 0 ) {
|
|
2688
|
+ /* FIXME: this implementation allows only a single QP
|
|
2689
|
+ * per multicast group, and doesn't handle hash
|
|
2690
|
+ * collisions. Sufficient for IPoIB but may need to
|
|
2691
|
+ * be extended in future.
|
|
2692
|
+ */
|
|
2693
|
+ DBGC ( arbel, "Arbel %p MGID index %#x already in use\n",
|
|
2694
|
+ arbel, index );
|
|
2695
|
+ return -EBUSY;
|
|
2696
|
+ }
|
|
2697
|
+
|
|
2698
|
+ /* Update hash table entry */
|
|
2699
|
+ MLX_FILL_2 ( &mgm, 8,
|
|
2700
|
+ mgmqp_0.qpn_i, qp->qpn,
|
|
2701
|
+ mgmqp_0.qi, 1 );
|
|
2702
|
+ memcpy ( &mgm.u.dwords[4], gid, sizeof ( *gid ) );
|
|
2703
|
+ if ( ( rc = arbel_cmd_write_mgm ( arbel, index, &mgm ) ) != 0 ) {
|
|
2704
|
+ DBGC ( arbel, "Arbel %p could not write MGM %#x: %s\n",
|
|
2705
|
+ arbel, index, strerror ( rc ) );
|
|
2706
|
+ return rc;
|
|
2707
|
+ }
|
|
2708
|
+
|
|
2709
|
+ return 0;
|
|
2710
|
+}
|
|
2711
|
+
|
|
2712
|
+/**
|
|
2713
|
+ * Detach from multicast group
|
|
2714
|
+ *
|
|
2715
|
+ * @v ibdev Infiniband device
|
|
2716
|
+ * @v qp Queue pair
|
|
2717
|
+ * @v gid Multicast GID
|
|
2718
|
+ */
|
|
2719
|
+static void arbel_mcast_detach ( struct ib_device *ibdev,
|
|
2720
|
+ struct ib_queue_pair *qp __unused,
|
|
2721
|
+ union ib_gid *gid ) {
|
|
2722
|
+ struct arbel *arbel = ib_get_drvdata ( ibdev );
|
|
2723
|
+ struct arbelprm_mgm_hash hash;
|
|
2724
|
+ struct arbelprm_mgm_entry mgm;
|
|
2725
|
+ unsigned int index;
|
|
2726
|
+ int rc;
|
|
2727
|
+
|
|
2728
|
+ /* Generate hash table index */
|
|
2729
|
+ if ( ( rc = arbel_cmd_mgid_hash ( arbel, gid, &hash ) ) != 0 ) {
|
|
2730
|
+ DBGC ( arbel, "Arbel %p could not hash GID: %s\n",
|
|
2731
|
+ arbel, strerror ( rc ) );
|
|
2732
|
+ return;
|
|
2733
|
+ }
|
|
2734
|
+ index = MLX_GET ( &hash, hash );
|
|
2735
|
+
|
|
2736
|
+ /* Clear hash table entry */
|
|
2737
|
+ memset ( &mgm, 0, sizeof ( mgm ) );
|
|
2738
|
+ if ( ( rc = arbel_cmd_write_mgm ( arbel, index, &mgm ) ) != 0 ) {
|
|
2739
|
+ DBGC ( arbel, "Arbel %p could not write MGM %#x: %s\n",
|
|
2740
|
+ arbel, index, strerror ( rc ) );
|
|
2741
|
+ return;
|
|
2742
|
+ }
|
|
2743
|
+}
|
|
2744
|
+
|
|
2745
|
+/** Arbel Infiniband operations */
|
|
2746
|
+static struct ib_device_operations arbel_ib_operations = {
|
|
2747
|
+ .create_cq = arbel_create_cq,
|
|
2748
|
+ .destroy_cq = arbel_destroy_cq,
|
|
2749
|
+ .create_qp = arbel_create_qp,
|
|
2750
|
+ .modify_qp = arbel_modify_qp,
|
|
2751
|
+ .destroy_qp = arbel_destroy_qp,
|
|
2752
|
+ .post_send = arbel_post_send,
|
|
2753
|
+ .post_recv = arbel_post_recv,
|
|
2754
|
+ .poll_cq = arbel_poll_cq,
|
|
2755
|
+ .poll_eq = arbel_poll_eq,
|
|
2756
|
+ .open = arbel_open,
|
|
2757
|
+ .close = arbel_close,
|
|
2758
|
+ .mcast_attach = arbel_mcast_attach,
|
|
2759
|
+ .mcast_detach = arbel_mcast_detach,
|
|
2760
|
+ .set_port_info = arbel_inform_sma,
|
|
2761
|
+ .set_pkey_table = arbel_inform_sma,
|
|
2762
|
+};
|
|
2763
|
+
|
|
2764
|
+/***************************************************************************
|
|
2765
|
+ *
|
|
2766
|
+ * PCI interface
|
|
2767
|
+ *
|
|
2768
|
+ ***************************************************************************
|
|
2769
|
+ */
|
|
2770
|
+
|
2764
|
2771
|
/**
|
2765
|
2772
|
* Probe PCI device
|
2766
|
2773
|
*
|