|
@@ -2136,7 +2136,7 @@ static int hermon_map_vpm ( struct hermon *hermon,
|
2136
|
2136
|
static int hermon_start_firmware ( struct hermon *hermon ) {
|
2137
|
2137
|
struct hermonprm_query_fw fw;
|
2138
|
2138
|
unsigned int fw_pages;
|
2139
|
|
- size_t fw_size;
|
|
2139
|
+ size_t fw_len;
|
2140
|
2140
|
physaddr_t fw_base;
|
2141
|
2141
|
int rc;
|
2142
|
2142
|
|
|
@@ -2154,17 +2154,22 @@ static int hermon_start_firmware ( struct hermon *hermon ) {
|
2154
|
2154
|
hermon, fw_pages, ( fw_pages * 4 ) );
|
2155
|
2155
|
|
2156
|
2156
|
/* Allocate firmware pages and map firmware area */
|
2157
|
|
- fw_size = ( fw_pages * HERMON_PAGE_SIZE );
|
2158
|
|
- hermon->firmware_area = umalloc ( fw_size );
|
|
2157
|
+ fw_len = ( fw_pages * HERMON_PAGE_SIZE );
|
2159
|
2158
|
if ( ! hermon->firmware_area ) {
|
2160
|
|
- rc = -ENOMEM;
|
2161
|
|
- goto err_alloc_fa;
|
|
2159
|
+ hermon->firmware_len = fw_len;
|
|
2160
|
+ hermon->firmware_area = umalloc ( hermon->firmware_len );
|
|
2161
|
+ if ( ! hermon->firmware_area ) {
|
|
2162
|
+ rc = -ENOMEM;
|
|
2163
|
+ goto err_alloc_fa;
|
|
2164
|
+ }
|
|
2165
|
+ } else {
|
|
2166
|
+ assert ( hermon->firmware_len == fw_len );
|
2162
|
2167
|
}
|
2163
|
2168
|
fw_base = user_to_phys ( hermon->firmware_area, 0 );
|
2164
|
2169
|
DBGC ( hermon, "Hermon %p firmware area at physical [%08lx,%08lx)\n",
|
2165
|
|
- hermon, fw_base, ( fw_base + fw_size ) );
|
|
2170
|
+ hermon, fw_base, ( fw_base + fw_len ) );
|
2166
|
2171
|
if ( ( rc = hermon_map_vpm ( hermon, hermon_cmd_map_fa,
|
2167
|
|
- 0, fw_base, fw_size ) ) != 0 ) {
|
|
2172
|
+ 0, fw_base, fw_len ) ) != 0 ) {
|
2168
|
2173
|
DBGC ( hermon, "Hermon %p could not map firmware: %s\n",
|
2169
|
2174
|
hermon, strerror ( rc ) );
|
2170
|
2175
|
goto err_map_fa;
|
|
@@ -2183,8 +2188,6 @@ static int hermon_start_firmware ( struct hermon *hermon ) {
|
2183
|
2188
|
err_run_fw:
|
2184
|
2189
|
err_map_fa:
|
2185
|
2190
|
hermon_cmd_unmap_fa ( hermon );
|
2186
|
|
- ufree ( hermon->firmware_area );
|
2187
|
|
- hermon->firmware_area = UNULL;
|
2188
|
2191
|
err_alloc_fa:
|
2189
|
2192
|
err_query_fw:
|
2190
|
2193
|
return rc;
|
|
@@ -2202,10 +2205,9 @@ static void hermon_stop_firmware ( struct hermon *hermon ) {
|
2202
|
2205
|
DBGC ( hermon, "Hermon %p FATAL could not stop firmware: %s\n",
|
2203
|
2206
|
hermon, strerror ( rc ) );
|
2204
|
2207
|
/* Leak memory and return; at least we avoid corruption */
|
|
2208
|
+ hermon->firmware_area = UNULL;
|
2205
|
2209
|
return;
|
2206
|
2210
|
}
|
2207
|
|
- ufree ( hermon->firmware_area );
|
2208
|
|
- hermon->firmware_area = UNULL;
|
2209
|
2211
|
}
|
2210
|
2212
|
|
2211
|
2213
|
/***************************************************************************
|
|
@@ -2285,14 +2287,14 @@ static uint64_t icm_align ( uint64_t icm_offset, size_t len ) {
|
2285
|
2287
|
}
|
2286
|
2288
|
|
2287
|
2289
|
/**
|
2288
|
|
- * Allocate ICM
|
|
2290
|
+ * Map ICM (allocating if necessary)
|
2289
|
2291
|
*
|
2290
|
2292
|
* @v hermon Hermon device
|
2291
|
2293
|
* @v init_hca INIT_HCA structure to fill in
|
2292
|
2294
|
* @ret rc Return status code
|
2293
|
2295
|
*/
|
2294
|
|
-static int hermon_alloc_icm ( struct hermon *hermon,
|
2295
|
|
- struct hermonprm_init_hca *init_hca ) {
|
|
2296
|
+static int hermon_map_icm ( struct hermon *hermon,
|
|
2297
|
+ struct hermonprm_init_hca *init_hca ) {
|
2296
|
2298
|
struct hermonprm_scalar_parameter icm_size;
|
2297
|
2299
|
struct hermonprm_scalar_parameter icm_aux_size;
|
2298
|
2300
|
uint64_t icm_offset = 0;
|
|
@@ -2519,10 +2521,17 @@ static int hermon_alloc_icm ( struct hermon *hermon,
|
2519
|
2521
|
/* Allocate ICM data and auxiliary area */
|
2520
|
2522
|
DBGC ( hermon, "Hermon %p requires %zd kB ICM and %zd kB AUX ICM\n",
|
2521
|
2523
|
hermon, ( icm_len / 1024 ), ( icm_aux_len / 1024 ) );
|
2522
|
|
- hermon->icm = umalloc ( icm_aux_len + icm_len );
|
2523
|
2524
|
if ( ! hermon->icm ) {
|
2524
|
|
- rc = -ENOMEM;
|
2525
|
|
- goto err_alloc;
|
|
2525
|
+ hermon->icm_len = icm_len;
|
|
2526
|
+ hermon->icm_aux_len = icm_aux_len;
|
|
2527
|
+ hermon->icm = umalloc ( hermon->icm_aux_len + hermon->icm_len );
|
|
2528
|
+ if ( ! hermon->icm ) {
|
|
2529
|
+ rc = -ENOMEM;
|
|
2530
|
+ goto err_alloc;
|
|
2531
|
+ }
|
|
2532
|
+ } else {
|
|
2533
|
+ assert ( hermon->icm_len == icm_len );
|
|
2534
|
+ assert ( hermon->icm_aux_len == icm_aux_len );
|
2526
|
2535
|
}
|
2527
|
2536
|
icm_phys = user_to_phys ( hermon->icm, 0 );
|
2528
|
2537
|
|
|
@@ -2559,19 +2568,17 @@ static int hermon_alloc_icm ( struct hermon *hermon,
|
2559
|
2568
|
assert ( i == 0 ); /* We don't handle partial failure at present */
|
2560
|
2569
|
err_map_icm_aux:
|
2561
|
2570
|
hermon_cmd_unmap_icm_aux ( hermon );
|
2562
|
|
- ufree ( hermon->icm );
|
2563
|
|
- hermon->icm = UNULL;
|
2564
|
2571
|
err_alloc:
|
2565
|
2572
|
err_set_icm_size:
|
2566
|
2573
|
return rc;
|
2567
|
2574
|
}
|
2568
|
2575
|
|
2569
|
2576
|
/**
|
2570
|
|
- * Free ICM
|
|
2577
|
+ * Unmap ICM
|
2571
|
2578
|
*
|
2572
|
2579
|
* @v hermon Hermon device
|
2573
|
2580
|
*/
|
2574
|
|
-static void hermon_free_icm ( struct hermon *hermon ) {
|
|
2581
|
+static void hermon_unmap_icm ( struct hermon *hermon ) {
|
2575
|
2582
|
struct hermonprm_scalar_parameter unmap_icm;
|
2576
|
2583
|
int i;
|
2577
|
2584
|
|
|
@@ -2587,13 +2594,11 @@ static void hermon_free_icm ( struct hermon *hermon ) {
|
2587
|
2594
|
&unmap_icm );
|
2588
|
2595
|
}
|
2589
|
2596
|
hermon_cmd_unmap_icm_aux ( hermon );
|
2590
|
|
- ufree ( hermon->icm );
|
2591
|
|
- hermon->icm = UNULL;
|
2592
|
2597
|
}
|
2593
|
2598
|
|
2594
|
2599
|
/***************************************************************************
|
2595
|
2600
|
*
|
2596
|
|
- * Initialisation
|
|
2601
|
+ * Initialisation and teardown
|
2597
|
2602
|
*
|
2598
|
2603
|
***************************************************************************
|
2599
|
2604
|
*/
|
|
@@ -2602,19 +2607,22 @@ static void hermon_free_icm ( struct hermon *hermon ) {
|
2602
|
2607
|
* Reset device
|
2603
|
2608
|
*
|
2604
|
2609
|
* @v hermon Hermon device
|
2605
|
|
- * @v pci PCI device
|
2606
|
2610
|
*/
|
2607
|
|
-static void hermon_reset ( struct hermon *hermon,
|
2608
|
|
- struct pci_device *pci ) {
|
|
2611
|
+static void hermon_reset ( struct hermon *hermon ) {
|
|
2612
|
+ struct pci_device *pci = hermon->pci;
|
2609
|
2613
|
struct pci_config_backup backup;
|
2610
|
2614
|
static const uint8_t backup_exclude[] =
|
2611
|
2615
|
PCI_CONFIG_BACKUP_EXCLUDE ( 0x58, 0x5c );
|
2612
|
2616
|
|
|
2617
|
+ /* Perform device reset and preserve PCI configuration */
|
2613
|
2618
|
pci_backup ( pci, &backup, backup_exclude );
|
2614
|
2619
|
writel ( HERMON_RESET_MAGIC,
|
2615
|
2620
|
( hermon->config + HERMON_RESET_OFFSET ) );
|
2616
|
2621
|
mdelay ( HERMON_RESET_WAIT_TIME_MS );
|
2617
|
2622
|
pci_restore ( pci, &backup, backup_exclude );
|
|
2623
|
+
|
|
2624
|
+ /* Reset command interface toggle */
|
|
2625
|
+ hermon->toggle = 0;
|
2618
|
2626
|
}
|
2619
|
2627
|
|
2620
|
2628
|
/**
|
|
@@ -2686,6 +2694,118 @@ static int hermon_configure_special_qps ( struct hermon *hermon ) {
|
2686
|
2694
|
return 0;
|
2687
|
2695
|
}
|
2688
|
2696
|
|
|
2697
|
+/**
|
|
2698
|
+ * Start Hermon device
|
|
2699
|
+ *
|
|
2700
|
+ * @v hermon Hermon device
|
|
2701
|
+ * @v running Firmware is already running
|
|
2702
|
+ * @ret rc Return status code
|
|
2703
|
+ */
|
|
2704
|
+static int hermon_start ( struct hermon *hermon, int running ) {
|
|
2705
|
+ struct hermonprm_init_hca init_hca;
|
|
2706
|
+ unsigned int i;
|
|
2707
|
+ int rc;
|
|
2708
|
+
|
|
2709
|
+ /* Start firmware if not already running */
|
|
2710
|
+ if ( ! running ) {
|
|
2711
|
+ if ( ( rc = hermon_start_firmware ( hermon ) ) != 0 )
|
|
2712
|
+ goto err_start_firmware;
|
|
2713
|
+ }
|
|
2714
|
+
|
|
2715
|
+ /* Allocate and map ICM */
|
|
2716
|
+ memset ( &init_hca, 0, sizeof ( init_hca ) );
|
|
2717
|
+ if ( ( rc = hermon_map_icm ( hermon, &init_hca ) ) != 0 )
|
|
2718
|
+ goto err_map_icm;
|
|
2719
|
+
|
|
2720
|
+ /* Initialise HCA */
|
|
2721
|
+ MLX_FILL_1 ( &init_hca, 0, version, 0x02 /* "Must be 0x02" */ );
|
|
2722
|
+ MLX_FILL_1 ( &init_hca, 5, udp, 1 );
|
|
2723
|
+ MLX_FILL_1 ( &init_hca, 74, uar_parameters.log_max_uars, 8 );
|
|
2724
|
+ if ( ( rc = hermon_cmd_init_hca ( hermon, &init_hca ) ) != 0 ) {
|
|
2725
|
+ DBGC ( hermon, "Hermon %p could not initialise HCA: %s\n",
|
|
2726
|
+ hermon, strerror ( rc ) );
|
|
2727
|
+ goto err_init_hca;
|
|
2728
|
+ }
|
|
2729
|
+
|
|
2730
|
+ /* Set up memory protection */
|
|
2731
|
+ if ( ( rc = hermon_setup_mpt ( hermon ) ) != 0 )
|
|
2732
|
+ goto err_setup_mpt;
|
|
2733
|
+ for ( i = 0 ; i < hermon->cap.num_ports ; i++ )
|
|
2734
|
+ hermon->port[i].ibdev->rdma_key = hermon->lkey;
|
|
2735
|
+
|
|
2736
|
+ /* Set up event queue */
|
|
2737
|
+ if ( ( rc = hermon_create_eq ( hermon ) ) != 0 )
|
|
2738
|
+ goto err_create_eq;
|
|
2739
|
+
|
|
2740
|
+ /* Configure special QPs */
|
|
2741
|
+ if ( ( rc = hermon_configure_special_qps ( hermon ) ) != 0 )
|
|
2742
|
+ goto err_conf_special_qps;
|
|
2743
|
+
|
|
2744
|
+ return 0;
|
|
2745
|
+
|
|
2746
|
+ err_conf_special_qps:
|
|
2747
|
+ hermon_destroy_eq ( hermon );
|
|
2748
|
+ err_create_eq:
|
|
2749
|
+ err_setup_mpt:
|
|
2750
|
+ hermon_cmd_close_hca ( hermon );
|
|
2751
|
+ err_init_hca:
|
|
2752
|
+ hermon_unmap_icm ( hermon );
|
|
2753
|
+ err_map_icm:
|
|
2754
|
+ hermon_stop_firmware ( hermon );
|
|
2755
|
+ err_start_firmware:
|
|
2756
|
+ return rc;
|
|
2757
|
+}
|
|
2758
|
+
|
|
2759
|
+/**
|
|
2760
|
+ * Stop Hermon device
|
|
2761
|
+ *
|
|
2762
|
+ * @v hermon Hermon device
|
|
2763
|
+ */
|
|
2764
|
+static void hermon_stop ( struct hermon *hermon ) {
|
|
2765
|
+ hermon_destroy_eq ( hermon );
|
|
2766
|
+ hermon_cmd_close_hca ( hermon );
|
|
2767
|
+ hermon_unmap_icm ( hermon );
|
|
2768
|
+ hermon_stop_firmware ( hermon );
|
|
2769
|
+ hermon_reset ( hermon );
|
|
2770
|
+}
|
|
2771
|
+
|
|
2772
|
+/**
|
|
2773
|
+ * Open Hermon device
|
|
2774
|
+ *
|
|
2775
|
+ * @v hermon Hermon device
|
|
2776
|
+ * @ret rc Return status code
|
|
2777
|
+ */
|
|
2778
|
+static int hermon_open ( struct hermon *hermon ) {
|
|
2779
|
+ int rc;
|
|
2780
|
+
|
|
2781
|
+ /* Start device if applicable */
|
|
2782
|
+ if ( hermon->open_count == 0 ) {
|
|
2783
|
+ if ( ( rc = hermon_start ( hermon, 0 ) ) != 0 )
|
|
2784
|
+ return rc;
|
|
2785
|
+ }
|
|
2786
|
+
|
|
2787
|
+ /* Increment open counter */
|
|
2788
|
+ hermon->open_count++;
|
|
2789
|
+
|
|
2790
|
+ return 0;
|
|
2791
|
+}
|
|
2792
|
+
|
|
2793
|
+/**
|
|
2794
|
+ * Close Hermon device
|
|
2795
|
+ *
|
|
2796
|
+ * @v hermon Hermon device
|
|
2797
|
+ */
|
|
2798
|
+static void hermon_close ( struct hermon *hermon ) {
|
|
2799
|
+
|
|
2800
|
+ /* Decrement open counter */
|
|
2801
|
+ assert ( hermon->open_count != 0 );
|
|
2802
|
+ hermon->open_count--;
|
|
2803
|
+
|
|
2804
|
+ /* Stop device if applicable */
|
|
2805
|
+ if ( hermon->open_count == 0 )
|
|
2806
|
+ hermon_stop ( hermon );
|
|
2807
|
+}
|
|
2808
|
+
|
2689
|
2809
|
/***************************************************************************
|
2690
|
2810
|
*
|
2691
|
2811
|
* Infiniband link-layer operations
|
|
@@ -2699,11 +2819,15 @@ static int hermon_configure_special_qps ( struct hermon *hermon ) {
|
2699
|
2819
|
* @v ibdev Infiniband device
|
2700
|
2820
|
* @ret rc Return status code
|
2701
|
2821
|
*/
|
2702
|
|
-static int hermon_open ( struct ib_device *ibdev ) {
|
|
2822
|
+static int hermon_ib_open ( struct ib_device *ibdev ) {
|
2703
|
2823
|
struct hermon *hermon = ib_get_drvdata ( ibdev );
|
2704
|
2824
|
union hermonprm_set_port set_port;
|
2705
|
2825
|
int rc;
|
2706
|
2826
|
|
|
2827
|
+ /* Open hardware */
|
|
2828
|
+ if ( ( rc = hermon_open ( hermon ) ) != 0 )
|
|
2829
|
+ goto err_open;
|
|
2830
|
+
|
2707
|
2831
|
/* Set port parameters */
|
2708
|
2832
|
memset ( &set_port, 0, sizeof ( set_port ) );
|
2709
|
2833
|
MLX_FILL_8 ( &set_port.ib, 0,
|
|
@@ -2724,20 +2848,26 @@ static int hermon_open ( struct ib_device *ibdev ) {
|
2724
|
2848
|
&set_port ) ) != 0 ) {
|
2725
|
2849
|
DBGC ( hermon, "Hermon %p port %d could not set port: %s\n",
|
2726
|
2850
|
hermon, ibdev->port, strerror ( rc ) );
|
2727
|
|
- return rc;
|
|
2851
|
+ goto err_set_port;
|
2728
|
2852
|
}
|
2729
|
2853
|
|
2730
|
2854
|
/* Initialise port */
|
2731
|
2855
|
if ( ( rc = hermon_cmd_init_port ( hermon, ibdev->port ) ) != 0 ) {
|
2732
|
2856
|
DBGC ( hermon, "Hermon %p port %d could not initialise port: "
|
2733
|
2857
|
"%s\n", hermon, ibdev->port, strerror ( rc ) );
|
2734
|
|
- return rc;
|
|
2858
|
+ goto err_init_port;
|
2735
|
2859
|
}
|
2736
|
2860
|
|
2737
|
2861
|
/* Update MAD parameters */
|
2738
|
2862
|
ib_smc_update ( ibdev, hermon_mad );
|
2739
|
2863
|
|
2740
|
2864
|
return 0;
|
|
2865
|
+
|
|
2866
|
+ err_init_port:
|
|
2867
|
+ err_set_port:
|
|
2868
|
+ hermon_close ( hermon );
|
|
2869
|
+ err_open:
|
|
2870
|
+ return rc;
|
2741
|
2871
|
}
|
2742
|
2872
|
|
2743
|
2873
|
/**
|
|
@@ -2745,15 +2875,19 @@ static int hermon_open ( struct ib_device *ibdev ) {
|
2745
|
2875
|
*
|
2746
|
2876
|
* @v ibdev Infiniband device
|
2747
|
2877
|
*/
|
2748
|
|
-static void hermon_close ( struct ib_device *ibdev ) {
|
|
2878
|
+static void hermon_ib_close ( struct ib_device *ibdev ) {
|
2749
|
2879
|
struct hermon *hermon = ib_get_drvdata ( ibdev );
|
2750
|
2880
|
int rc;
|
2751
|
2881
|
|
|
2882
|
+ /* Close port */
|
2752
|
2883
|
if ( ( rc = hermon_cmd_close_port ( hermon, ibdev->port ) ) != 0 ) {
|
2753
|
2884
|
DBGC ( hermon, "Hermon %p port %d could not close port: %s\n",
|
2754
|
2885
|
hermon, ibdev->port, strerror ( rc ) );
|
2755
|
2886
|
/* Nothing we can do about this */
|
2756
|
2887
|
}
|
|
2888
|
+
|
|
2889
|
+ /* Close hardware */
|
|
2890
|
+ hermon_close ( hermon );
|
2757
|
2891
|
}
|
2758
|
2892
|
|
2759
|
2893
|
/**
|
|
@@ -2883,8 +3017,8 @@ static struct ib_device_operations hermon_ib_operations = {
|
2883
|
3017
|
.post_recv = hermon_post_recv,
|
2884
|
3018
|
.poll_cq = hermon_poll_cq,
|
2885
|
3019
|
.poll_eq = hermon_poll_eq,
|
2886
|
|
- .open = hermon_open,
|
2887
|
|
- .close = hermon_close,
|
|
3020
|
+ .open = hermon_ib_open,
|
|
3021
|
+ .close = hermon_ib_close,
|
2888
|
3022
|
.mcast_attach = hermon_mcast_attach,
|
2889
|
3023
|
.mcast_detach = hermon_mcast_detach,
|
2890
|
3024
|
.set_port_info = hermon_inform_sma,
|
|
@@ -3073,6 +3207,10 @@ static int hermon_eth_open ( struct net_device *netdev ) {
|
3073
|
3207
|
union hermonprm_set_port set_port;
|
3074
|
3208
|
int rc;
|
3075
|
3209
|
|
|
3210
|
+ /* Open hardware */
|
|
3211
|
+ if ( ( rc = hermon_open ( hermon ) ) != 0 )
|
|
3212
|
+ goto err_open;
|
|
3213
|
+
|
3076
|
3214
|
/* Allocate completion queue */
|
3077
|
3215
|
port->eth_cq = ib_create_cq ( ibdev, HERMON_ETH_NUM_CQES,
|
3078
|
3216
|
&hermon_eth_cq_op );
|
|
@@ -3167,6 +3305,8 @@ static int hermon_eth_open ( struct net_device *netdev ) {
|
3167
|
3305
|
err_create_qp:
|
3168
|
3306
|
ib_destroy_cq ( ibdev, port->eth_cq );
|
3169
|
3307
|
err_create_cq:
|
|
3308
|
+ hermon_close ( hermon );
|
|
3309
|
+ err_open:
|
3170
|
3310
|
return rc;
|
3171
|
3311
|
}
|
3172
|
3312
|
|
|
@@ -3191,6 +3331,9 @@ static void hermon_eth_close ( struct net_device *netdev ) {
|
3191
|
3331
|
/* Tear down the queues */
|
3192
|
3332
|
ib_destroy_qp ( ibdev, port->eth_qp );
|
3193
|
3333
|
ib_destroy_cq ( ibdev, port->eth_cq );
|
|
3334
|
+
|
|
3335
|
+ /* Close hardware */
|
|
3336
|
+ hermon_close ( hermon );
|
3194
|
3337
|
}
|
3195
|
3338
|
|
3196
|
3339
|
/** Hermon Ethernet network device operations */
|
|
@@ -3562,6 +3705,8 @@ static struct hermon * hermon_alloc ( void ) {
|
3562
|
3705
|
*/
|
3563
|
3706
|
static void hermon_free ( struct hermon *hermon ) {
|
3564
|
3707
|
|
|
3708
|
+ ufree ( hermon->icm );
|
|
3709
|
+ ufree ( hermon->firmware_area );
|
3565
|
3710
|
free_dma ( hermon->mailbox_out, HERMON_MBOX_SIZE );
|
3566
|
3711
|
free_dma ( hermon->mailbox_in, HERMON_MBOX_SIZE );
|
3567
|
3712
|
free ( hermon );
|
|
@@ -3571,9 +3716,9 @@ static void hermon_free ( struct hermon *hermon ) {
|
3571
|
3716
|
* Initialise Hermon PCI parameters
|
3572
|
3717
|
*
|
3573
|
3718
|
* @v hermon Hermon device
|
3574
|
|
- * @v pci PCI device
|
3575
|
3719
|
*/
|
3576
|
|
-static void hermon_pci_init ( struct hermon *hermon, struct pci_device *pci ) {
|
|
3720
|
+static void hermon_pci_init ( struct hermon *hermon ) {
|
|
3721
|
+ struct pci_device *pci = hermon->pci;
|
3577
|
3722
|
|
3578
|
3723
|
/* Fix up PCI device */
|
3579
|
3724
|
adjust_pci_device ( pci );
|
|
@@ -3597,7 +3742,6 @@ static int hermon_probe ( struct pci_device *pci ) {
|
3597
|
3742
|
struct ib_device *ibdev;
|
3598
|
3743
|
struct net_device *netdev;
|
3599
|
3744
|
struct hermon_port *port;
|
3600
|
|
- struct hermonprm_init_hca init_hca;
|
3601
|
3745
|
unsigned int i;
|
3602
|
3746
|
int rc;
|
3603
|
3747
|
|
|
@@ -3608,12 +3752,13 @@ static int hermon_probe ( struct pci_device *pci ) {
|
3608
|
3752
|
goto err_alloc;
|
3609
|
3753
|
}
|
3610
|
3754
|
pci_set_drvdata ( pci, hermon );
|
|
3755
|
+ hermon->pci = pci;
|
3611
|
3756
|
|
3612
|
3757
|
/* Initialise PCI parameters */
|
3613
|
|
- hermon_pci_init ( hermon, pci );
|
|
3758
|
+ hermon_pci_init ( hermon );
|
3614
|
3759
|
|
3615
|
3760
|
/* Reset device */
|
3616
|
|
- hermon_reset ( hermon, pci );
|
|
3761
|
+ hermon_reset ( hermon );
|
3617
|
3762
|
|
3618
|
3763
|
/* Start firmware */
|
3619
|
3764
|
if ( ( rc = hermon_start_firmware ( hermon ) ) != 0 )
|
|
@@ -3650,34 +3795,9 @@ static int hermon_probe ( struct pci_device *pci ) {
|
3650
|
3795
|
netdev->priv = &hermon->port[i];
|
3651
|
3796
|
}
|
3652
|
3797
|
|
3653
|
|
- /* Allocate ICM */
|
3654
|
|
- memset ( &init_hca, 0, sizeof ( init_hca ) );
|
3655
|
|
- if ( ( rc = hermon_alloc_icm ( hermon, &init_hca ) ) != 0 )
|
3656
|
|
- goto err_alloc_icm;
|
3657
|
|
-
|
3658
|
|
- /* Initialise HCA */
|
3659
|
|
- MLX_FILL_1 ( &init_hca, 0, version, 0x02 /* "Must be 0x02" */ );
|
3660
|
|
- MLX_FILL_1 ( &init_hca, 5, udp, 1 );
|
3661
|
|
- MLX_FILL_1 ( &init_hca, 74, uar_parameters.log_max_uars, 8 );
|
3662
|
|
- if ( ( rc = hermon_cmd_init_hca ( hermon, &init_hca ) ) != 0 ) {
|
3663
|
|
- DBGC ( hermon, "Hermon %p could not initialise HCA: %s\n",
|
3664
|
|
- hermon, strerror ( rc ) );
|
3665
|
|
- goto err_init_hca;
|
3666
|
|
- }
|
3667
|
|
-
|
3668
|
|
- /* Set up memory protection */
|
3669
|
|
- if ( ( rc = hermon_setup_mpt ( hermon ) ) != 0 )
|
3670
|
|
- goto err_setup_mpt;
|
3671
|
|
- for ( i = 0 ; i < hermon->cap.num_ports ; i++ )
|
3672
|
|
- hermon->port[i].ibdev->rdma_key = hermon->lkey;
|
3673
|
|
-
|
3674
|
|
- /* Set up event queue */
|
3675
|
|
- if ( ( rc = hermon_create_eq ( hermon ) ) != 0 )
|
3676
|
|
- goto err_create_eq;
|
3677
|
|
-
|
3678
|
|
- /* Configure special QPs */
|
3679
|
|
- if ( ( rc = hermon_configure_special_qps ( hermon ) ) != 0 )
|
3680
|
|
- goto err_conf_special_qps;
|
|
3798
|
+ /* Start device */
|
|
3799
|
+ if ( ( rc = hermon_start ( hermon, 1 ) ) != 0 )
|
|
3800
|
+ goto err_start;
|
3681
|
3801
|
|
3682
|
3802
|
/* Determine port types */
|
3683
|
3803
|
for ( i = 0 ; i < hermon->cap.num_ports ; i++ ) {
|
|
@@ -3693,6 +3813,10 @@ static int hermon_probe ( struct pci_device *pci ) {
|
3693
|
3813
|
goto err_register;
|
3694
|
3814
|
}
|
3695
|
3815
|
|
|
3816
|
+ /* Leave device quiescent until opened */
|
|
3817
|
+ if ( hermon->open_count == 0 )
|
|
3818
|
+ hermon_stop ( hermon );
|
|
3819
|
+
|
3696
|
3820
|
return 0;
|
3697
|
3821
|
|
3698
|
3822
|
i = hermon->cap.num_ports;
|
|
@@ -3702,14 +3826,8 @@ static int hermon_probe ( struct pci_device *pci ) {
|
3702
|
3826
|
port->type->unregister_dev ( hermon, port );
|
3703
|
3827
|
}
|
3704
|
3828
|
err_set_port_type:
|
3705
|
|
- err_conf_special_qps:
|
3706
|
|
- hermon_destroy_eq ( hermon );
|
3707
|
|
- err_create_eq:
|
3708
|
|
- err_setup_mpt:
|
3709
|
|
- hermon_cmd_close_hca ( hermon );
|
3710
|
|
- err_init_hca:
|
3711
|
|
- hermon_free_icm ( hermon );
|
3712
|
|
- err_alloc_icm:
|
|
3829
|
+ hermon_stop ( hermon );
|
|
3830
|
+ err_start:
|
3713
|
3831
|
i = hermon->cap.num_ports;
|
3714
|
3832
|
err_alloc_netdev:
|
3715
|
3833
|
for ( i-- ; ( signed int ) i >= 0 ; i-- ) {
|
|
@@ -3742,10 +3860,6 @@ static void hermon_remove ( struct pci_device *pci ) {
|
3742
|
3860
|
port = &hermon->port[i];
|
3743
|
3861
|
port->type->unregister_dev ( hermon, port );
|
3744
|
3862
|
}
|
3745
|
|
- hermon_destroy_eq ( hermon );
|
3746
|
|
- hermon_cmd_close_hca ( hermon );
|
3747
|
|
- hermon_free_icm ( hermon );
|
3748
|
|
- hermon_stop_firmware ( hermon );
|
3749
|
3863
|
for ( i = ( hermon->cap.num_ports - 1 ) ; i >= 0 ; i-- ) {
|
3750
|
3864
|
netdev_nullify ( hermon->port[i].netdev );
|
3751
|
3865
|
netdev_put ( hermon->port[i].netdev );
|
|
@@ -3773,9 +3887,10 @@ static int hermon_bofm_probe ( struct pci_device *pci ) {
|
3773
|
3887
|
goto err_alloc;
|
3774
|
3888
|
}
|
3775
|
3889
|
pci_set_drvdata ( pci, hermon );
|
|
3890
|
+ hermon->pci = pci;
|
3776
|
3891
|
|
3777
|
3892
|
/* Initialise PCI parameters */
|
3778
|
|
- hermon_pci_init ( hermon, pci );
|
|
3893
|
+ hermon_pci_init ( hermon );
|
3779
|
3894
|
|
3780
|
3895
|
/* Initialise BOFM device */
|
3781
|
3896
|
bofm_init ( &hermon->bofm, pci, &hermon_bofm_operations );
|