@@ -141,6 +141,29 @@ static const struct ibmvnic_stat ibmvnic_stats[] = {
141141 {"internal_mac_rx_errors" , IBMVNIC_STAT_OFF (internal_mac_rx_errors )},
142142};
143143
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+
144167static long h_reg_sub_crq (unsigned long unit_address , unsigned long token ,
145168 unsigned long length , unsigned long * number ,
146169 unsigned long * irq )
@@ -2083,10 +2106,10 @@ static int do_reset(struct ibmvnic_adapter *adapter,
20832106 goto out ;
20842107 }
20852108
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,
20872110 * exit here.
20882111 */
2089- if (reset_state == VNIC_PROBED ) {
2112+ if (reset_state == VNIC_PROBED || reset_state == VNIC_DOWN ) {
20902113 rc = 0 ;
20912114 goto out ;
20922115 }
@@ -2212,10 +2235,10 @@ static int do_hard_reset(struct ibmvnic_adapter *adapter,
22122235 if (rc )
22132236 goto out ;
22142237
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,
22162239 * exit here.
22172240 */
2218- if (reset_state == VNIC_PROBED )
2241+ if (reset_state == VNIC_PROBED || reset_state == VNIC_DOWN )
22192242 goto out ;
22202243
22212244 rc = ibmvnic_login (netdev );
@@ -2268,6 +2291,76 @@ static struct ibmvnic_rwi *get_next_rwi(struct ibmvnic_adapter *adapter)
22682291 return rwi ;
22692292}
22702293
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+
22712364static void __ibmvnic_reset (struct work_struct * work )
22722365{
22732366 struct ibmvnic_rwi * rwi ;
@@ -2304,7 +2397,13 @@ static void __ibmvnic_reset(struct work_struct *work)
23042397 }
23052398 spin_unlock_irqrestore (& adapter -> state_lock , flags );
23062399
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 ) {
23082407 /* Since we are doing a hard reset now, clear the
23092408 * failover_pending flag so we don't ignore any
23102409 * future MOBILITY or other resets.
@@ -3773,18 +3872,6 @@ static int ibmvnic_send_crq_init(struct ibmvnic_adapter *adapter)
37733872 return 0 ;
37743873}
37753874
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-
37883875struct vnic_login_client_data {
37893876 u8 type ;
37903877 __be16 len ;
@@ -4904,7 +4991,12 @@ static void ibmvnic_handle_crq(union ibmvnic_crq *crq,
49044991 complete (& adapter -> init_done );
49054992 adapter -> init_done_rc = - EIO ;
49064993 }
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+
49085000 if (rc && rc != - EBUSY ) {
49095001 /* We were unable to schedule the failover
49105002 * 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)
53275419 struct ibmvnic_adapter * adapter ;
53285420 struct net_device * netdev ;
53295421 unsigned char * mac_addr_p ;
5422+ bool init_success ;
53305423 int rc ;
53315424
53325425 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)
53735466 init_completion (& adapter -> stats_done );
53745467 clear_bit (0 , & adapter -> resetting );
53755468
5469+ init_success = false;
53765470 do {
53775471 rc = init_crq_queue (adapter );
53785472 if (rc ) {
@@ -5382,10 +5476,16 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
53825476 }
53835477
53845478 rc = ibmvnic_reset_init (adapter , false);
5385- if (rc && rc != EAGAIN )
5386- goto ibmvnic_init_fail ;
53875479 } while (rc == EAGAIN );
53885480
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+
53895489 rc = init_stats_buffers (adapter );
53905490 if (rc )
53915491 goto ibmvnic_init_fail ;
@@ -5394,10 +5494,6 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
53945494 if (rc )
53955495 goto ibmvnic_stats_fail ;
53965496
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-
54015497 rc = device_create_file (& dev -> dev , & dev_attr_failover );
54025498 if (rc )
54035499 goto ibmvnic_dev_file_err ;
@@ -5410,7 +5506,14 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
54105506 }
54115507 dev_info (& dev -> dev , "ibmvnic registered\n" );
54125508
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+ }
54145517
54155518 adapter -> wait_for_reset = false;
54165519 adapter -> last_reset_time = jiffies ;
0 commit comments