33
33
enum {
34
34
PHYLINK_DISABLE_STOPPED ,
35
35
PHYLINK_DISABLE_LINK ,
36
+ PHYLINK_DISABLE_MAC_WOL ,
36
37
};
37
38
38
39
/**
@@ -1282,6 +1283,9 @@ EXPORT_SYMBOL_GPL(phylink_start);
1282
1283
* network device driver's &struct net_device_ops ndo_stop() method. The
1283
1284
* network device's carrier state should not be changed prior to calling this
1284
1285
* function.
1286
+ *
1287
+ * This will synchronously bring down the link if the link is not already
1288
+ * down (in other words, it will trigger a mac_link_down() method call.)
1285
1289
*/
1286
1290
void phylink_stop (struct phylink * pl )
1287
1291
{
@@ -1301,6 +1305,84 @@ void phylink_stop(struct phylink *pl)
1301
1305
}
1302
1306
EXPORT_SYMBOL_GPL (phylink_stop );
1303
1307
1308
+ /**
1309
+ * phylink_suspend() - handle a network device suspend event
1310
+ * @pl: a pointer to a &struct phylink returned from phylink_create()
1311
+ * @mac_wol: true if the MAC needs to receive packets for Wake-on-Lan
1312
+ *
1313
+ * Handle a network device suspend event. There are several cases:
1314
+ * - If Wake-on-Lan is not active, we can bring down the link between
1315
+ * the MAC and PHY by calling phylink_stop().
1316
+ * - If Wake-on-Lan is active, and being handled only by the PHY, we
1317
+ * can also bring down the link between the MAC and PHY.
1318
+ * - If Wake-on-Lan is active, but being handled by the MAC, the MAC
1319
+ * still needs to receive packets, so we can not bring the link down.
1320
+ */
1321
+ void phylink_suspend (struct phylink * pl , bool mac_wol )
1322
+ {
1323
+ ASSERT_RTNL ();
1324
+
1325
+ if (mac_wol && (!pl -> netdev || pl -> netdev -> wol_enabled )) {
1326
+ /* Wake-on-Lan enabled, MAC handling */
1327
+ mutex_lock (& pl -> state_mutex );
1328
+
1329
+ /* Stop the resolver bringing the link up */
1330
+ __set_bit (PHYLINK_DISABLE_MAC_WOL , & pl -> phylink_disable_state );
1331
+
1332
+ /* Disable the carrier, to prevent transmit timeouts,
1333
+ * but one would hope all packets have been sent. This
1334
+ * also means phylink_resolve() will do nothing.
1335
+ */
1336
+ netif_carrier_off (pl -> netdev );
1337
+
1338
+ /* We do not call mac_link_down() here as we want the
1339
+ * link to remain up to receive the WoL packets.
1340
+ */
1341
+ mutex_unlock (& pl -> state_mutex );
1342
+ } else {
1343
+ phylink_stop (pl );
1344
+ }
1345
+ }
1346
+ EXPORT_SYMBOL_GPL (phylink_suspend );
1347
+
1348
+ /**
1349
+ * phylink_resume() - handle a network device resume event
1350
+ * @pl: a pointer to a &struct phylink returned from phylink_create()
1351
+ *
1352
+ * Undo the effects of phylink_suspend(), returning the link to an
1353
+ * operational state.
1354
+ */
1355
+ void phylink_resume (struct phylink * pl )
1356
+ {
1357
+ ASSERT_RTNL ();
1358
+
1359
+ if (test_bit (PHYLINK_DISABLE_MAC_WOL , & pl -> phylink_disable_state )) {
1360
+ /* Wake-on-Lan enabled, MAC handling */
1361
+
1362
+ /* Call mac_link_down() so we keep the overall state balanced.
1363
+ * Do this under the state_mutex lock for consistency. This
1364
+ * will cause a "Link Down" message to be printed during
1365
+ * resume, which is harmless - the true link state will be
1366
+ * printed when we run a resolve.
1367
+ */
1368
+ mutex_lock (& pl -> state_mutex );
1369
+ phylink_link_down (pl );
1370
+ mutex_unlock (& pl -> state_mutex );
1371
+
1372
+ /* Re-apply the link parameters so that all the settings get
1373
+ * restored to the MAC.
1374
+ */
1375
+ phylink_mac_initial_config (pl , true);
1376
+
1377
+ /* Re-enable and re-resolve the link parameters */
1378
+ clear_bit (PHYLINK_DISABLE_MAC_WOL , & pl -> phylink_disable_state );
1379
+ phylink_run_resolve (pl );
1380
+ } else {
1381
+ phylink_start (pl );
1382
+ }
1383
+ }
1384
+ EXPORT_SYMBOL_GPL (phylink_resume );
1385
+
1304
1386
/**
1305
1387
* phylink_ethtool_get_wol() - get the wake on lan parameters for the PHY
1306
1388
* @pl: a pointer to a &struct phylink returned from phylink_create()
0 commit comments