@@ -141,6 +141,29 @@ static const struct ibmvnic_stat ibmvnic_stats[] = {
141
141
{"internal_mac_rx_errors" , IBMVNIC_STAT_OFF (internal_mac_rx_errors )},
142
142
};
143
143
144
+ static int send_crq_init_complete (struct ibmvnic_adapter * adapter )
145
+ {
146
+ union ibmvnic_crq crq ;
147
+
148
+ memset (& crq , 0 , sizeof (crq ));
149
+ crq .generic .first = IBMVNIC_CRQ_INIT_CMD ;
150
+ crq .generic .cmd = IBMVNIC_CRQ_INIT_COMPLETE ;
151
+
152
+ return ibmvnic_send_crq (adapter , & crq );
153
+ }
154
+
155
+ static int send_version_xchg (struct ibmvnic_adapter * adapter )
156
+ {
157
+ union ibmvnic_crq crq ;
158
+
159
+ memset (& crq , 0 , sizeof (crq ));
160
+ crq .version_exchange .first = IBMVNIC_CRQ_CMD ;
161
+ crq .version_exchange .cmd = VERSION_EXCHANGE ;
162
+ crq .version_exchange .version = cpu_to_be16 (ibmvnic_version );
163
+
164
+ return ibmvnic_send_crq (adapter , & crq );
165
+ }
166
+
144
167
static long h_reg_sub_crq (unsigned long unit_address , unsigned long token ,
145
168
unsigned long length , unsigned long * number ,
146
169
unsigned long * irq )
@@ -2083,10 +2106,10 @@ static int do_reset(struct ibmvnic_adapter *adapter,
2083
2106
goto out ;
2084
2107
}
2085
2108
2086
- /* If the adapter was in PROBE state prior to the reset,
2109
+ /* If the adapter was in PROBE or DOWN state prior to the reset,
2087
2110
* exit here.
2088
2111
*/
2089
- if (reset_state == VNIC_PROBED ) {
2112
+ if (reset_state == VNIC_PROBED || reset_state == VNIC_DOWN ) {
2090
2113
rc = 0 ;
2091
2114
goto out ;
2092
2115
}
@@ -2212,10 +2235,10 @@ static int do_hard_reset(struct ibmvnic_adapter *adapter,
2212
2235
if (rc )
2213
2236
goto out ;
2214
2237
2215
- /* If the adapter was in PROBE state prior to the reset,
2238
+ /* If the adapter was in PROBE or DOWN state prior to the reset,
2216
2239
* exit here.
2217
2240
*/
2218
- if (reset_state == VNIC_PROBED )
2241
+ if (reset_state == VNIC_PROBED || reset_state == VNIC_DOWN )
2219
2242
goto out ;
2220
2243
2221
2244
rc = ibmvnic_login (netdev );
@@ -2268,6 +2291,76 @@ static struct ibmvnic_rwi *get_next_rwi(struct ibmvnic_adapter *adapter)
2268
2291
return rwi ;
2269
2292
}
2270
2293
2294
+ /**
2295
+ * do_passive_init - complete probing when partner device is detected.
2296
+ * @adapter: ibmvnic_adapter struct
2297
+ *
2298
+ * If the ibmvnic device does not have a partner device to communicate with at boot
2299
+ * and that partner device comes online at a later time, this function is called
2300
+ * to complete the initialization process of ibmvnic device.
2301
+ * Caller is expected to hold rtnl_lock().
2302
+ *
2303
+ * Returns non-zero if sub-CRQs are not initialized properly leaving the device
2304
+ * in the down state.
2305
+ * Returns 0 upon success and the device is in PROBED state.
2306
+ */
2307
+
2308
+ static int do_passive_init (struct ibmvnic_adapter * adapter )
2309
+ {
2310
+ unsigned long timeout = msecs_to_jiffies (30000 );
2311
+ struct net_device * netdev = adapter -> netdev ;
2312
+ struct device * dev = & adapter -> vdev -> dev ;
2313
+ int rc ;
2314
+
2315
+ netdev_dbg (netdev , "Partner device found, probing.\n" );
2316
+
2317
+ adapter -> state = VNIC_PROBING ;
2318
+ reinit_completion (& adapter -> init_done );
2319
+ adapter -> init_done_rc = 0 ;
2320
+ adapter -> crq .active = true;
2321
+
2322
+ rc = send_crq_init_complete (adapter );
2323
+ if (rc )
2324
+ goto out ;
2325
+
2326
+ rc = send_version_xchg (adapter );
2327
+ if (rc )
2328
+ netdev_dbg (adapter -> netdev , "send_version_xchg failed, rc=%d\n" , rc );
2329
+
2330
+ if (!wait_for_completion_timeout (& adapter -> init_done , timeout )) {
2331
+ dev_err (dev , "Initialization sequence timed out\n" );
2332
+ rc = - ETIMEDOUT ;
2333
+ goto out ;
2334
+ }
2335
+
2336
+ rc = init_sub_crqs (adapter );
2337
+ if (rc ) {
2338
+ dev_err (dev , "Initialization of sub crqs failed, rc=%d\n" , rc );
2339
+ goto out ;
2340
+ }
2341
+
2342
+ rc = init_sub_crq_irqs (adapter );
2343
+ if (rc ) {
2344
+ dev_err (dev , "Failed to initialize sub crq irqs\n, rc=%d" , rc );
2345
+ goto init_failed ;
2346
+ }
2347
+
2348
+ netdev -> mtu = adapter -> req_mtu - ETH_HLEN ;
2349
+ netdev -> min_mtu = adapter -> min_mtu - ETH_HLEN ;
2350
+ netdev -> max_mtu = adapter -> max_mtu - ETH_HLEN ;
2351
+
2352
+ adapter -> state = VNIC_PROBED ;
2353
+ netdev_dbg (netdev , "Probed successfully. Waiting for signal from partner device.\n" );
2354
+
2355
+ return 0 ;
2356
+
2357
+ init_failed :
2358
+ release_sub_crqs (adapter , 1 );
2359
+ out :
2360
+ adapter -> state = VNIC_DOWN ;
2361
+ return rc ;
2362
+ }
2363
+
2271
2364
static void __ibmvnic_reset (struct work_struct * work )
2272
2365
{
2273
2366
struct ibmvnic_rwi * rwi ;
@@ -2304,7 +2397,13 @@ static void __ibmvnic_reset(struct work_struct *work)
2304
2397
}
2305
2398
spin_unlock_irqrestore (& adapter -> state_lock , flags );
2306
2399
2307
- if (adapter -> force_reset_recovery ) {
2400
+ if (rwi -> reset_reason == VNIC_RESET_PASSIVE_INIT ) {
2401
+ rtnl_lock ();
2402
+ rc = do_passive_init (adapter );
2403
+ rtnl_unlock ();
2404
+ if (!rc )
2405
+ netif_carrier_on (adapter -> netdev );
2406
+ } else if (adapter -> force_reset_recovery ) {
2308
2407
/* Since we are doing a hard reset now, clear the
2309
2408
* failover_pending flag so we don't ignore any
2310
2409
* future MOBILITY or other resets.
@@ -3773,18 +3872,6 @@ static int ibmvnic_send_crq_init(struct ibmvnic_adapter *adapter)
3773
3872
return 0 ;
3774
3873
}
3775
3874
3776
- static int send_version_xchg (struct ibmvnic_adapter * adapter )
3777
- {
3778
- union ibmvnic_crq crq ;
3779
-
3780
- memset (& crq , 0 , sizeof (crq ));
3781
- crq .version_exchange .first = IBMVNIC_CRQ_CMD ;
3782
- crq .version_exchange .cmd = VERSION_EXCHANGE ;
3783
- crq .version_exchange .version = cpu_to_be16 (ibmvnic_version );
3784
-
3785
- return ibmvnic_send_crq (adapter , & crq );
3786
- }
3787
-
3788
3875
struct vnic_login_client_data {
3789
3876
u8 type ;
3790
3877
__be16 len ;
@@ -4904,7 +4991,12 @@ static void ibmvnic_handle_crq(union ibmvnic_crq *crq,
4904
4991
complete (& adapter -> init_done );
4905
4992
adapter -> init_done_rc = - EIO ;
4906
4993
}
4907
- rc = ibmvnic_reset (adapter , VNIC_RESET_FAILOVER );
4994
+
4995
+ if (adapter -> state == VNIC_DOWN )
4996
+ rc = ibmvnic_reset (adapter , VNIC_RESET_PASSIVE_INIT );
4997
+ else
4998
+ rc = ibmvnic_reset (adapter , VNIC_RESET_FAILOVER );
4999
+
4908
5000
if (rc && rc != - EBUSY ) {
4909
5001
/* We were unable to schedule the failover
4910
5002
* reset either because the adapter was still
@@ -5327,6 +5419,7 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
5327
5419
struct ibmvnic_adapter * adapter ;
5328
5420
struct net_device * netdev ;
5329
5421
unsigned char * mac_addr_p ;
5422
+ bool init_success ;
5330
5423
int rc ;
5331
5424
5332
5425
dev_dbg (& dev -> dev , "entering ibmvnic_probe for UA 0x%x\n" ,
@@ -5373,6 +5466,7 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
5373
5466
init_completion (& adapter -> stats_done );
5374
5467
clear_bit (0 , & adapter -> resetting );
5375
5468
5469
+ init_success = false;
5376
5470
do {
5377
5471
rc = init_crq_queue (adapter );
5378
5472
if (rc ) {
@@ -5382,10 +5476,16 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
5382
5476
}
5383
5477
5384
5478
rc = ibmvnic_reset_init (adapter , false);
5385
- if (rc && rc != EAGAIN )
5386
- goto ibmvnic_init_fail ;
5387
5479
} while (rc == EAGAIN );
5388
5480
5481
+ /* We are ignoring the error from ibmvnic_reset_init() assuming that the
5482
+ * partner is not ready. CRQ is not active. When the partner becomes
5483
+ * ready, we will do the passive init reset.
5484
+ */
5485
+
5486
+ if (!rc )
5487
+ init_success = true;
5488
+
5389
5489
rc = init_stats_buffers (adapter );
5390
5490
if (rc )
5391
5491
goto ibmvnic_init_fail ;
@@ -5394,10 +5494,6 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
5394
5494
if (rc )
5395
5495
goto ibmvnic_stats_fail ;
5396
5496
5397
- netdev -> mtu = adapter -> req_mtu - ETH_HLEN ;
5398
- netdev -> min_mtu = adapter -> min_mtu - ETH_HLEN ;
5399
- netdev -> max_mtu = adapter -> max_mtu - ETH_HLEN ;
5400
-
5401
5497
rc = device_create_file (& dev -> dev , & dev_attr_failover );
5402
5498
if (rc )
5403
5499
goto ibmvnic_dev_file_err ;
@@ -5410,7 +5506,14 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
5410
5506
}
5411
5507
dev_info (& dev -> dev , "ibmvnic registered\n" );
5412
5508
5413
- adapter -> state = VNIC_PROBED ;
5509
+ if (init_success ) {
5510
+ adapter -> state = VNIC_PROBED ;
5511
+ netdev -> mtu = adapter -> req_mtu - ETH_HLEN ;
5512
+ netdev -> min_mtu = adapter -> min_mtu - ETH_HLEN ;
5513
+ netdev -> max_mtu = adapter -> max_mtu - ETH_HLEN ;
5514
+ } else {
5515
+ adapter -> state = VNIC_DOWN ;
5516
+ }
5414
5517
5415
5518
adapter -> wait_for_reset = false;
5416
5519
adapter -> last_reset_time = jiffies ;
0 commit comments