diff options
author | Masakazu Mokuno <mokuno@sm.sony.co.jp> | 2008-03-26 20:39:31 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2008-04-01 05:43:08 -0400 |
commit | 3faac21546f5b213cda490d45fe5927d713e44f1 (patch) | |
tree | 5f3bb9982747b6967b5ef68cfbed581fe9b47cbf /drivers/net/ps3_gelic_net.c | |
parent | 1c43d265f462bc714da67aa8113b3846bb9943e3 (diff) |
[POWERPC] PS3: Gelic network driver Wake-on-LAN support
Add Wake-on-LAN support to the PS3 Gelic network driver.
Other OS WOL support was introduced in PS3 system firmware 2.20.
Signed-off-by: Masakazu Mokuno <mokuno@sm.sony.co.jp>
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'drivers/net/ps3_gelic_net.c')
-rw-r--r-- | drivers/net/ps3_gelic_net.c | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c index 7eb6e7e848f4..e365efb3c627 100644 --- a/drivers/net/ps3_gelic_net.c +++ b/drivers/net/ps3_gelic_net.c | |||
@@ -1266,6 +1266,85 @@ int gelic_net_set_rx_csum(struct net_device *netdev, u32 data) | |||
1266 | return 0; | 1266 | return 0; |
1267 | } | 1267 | } |
1268 | 1268 | ||
1269 | static void gelic_net_get_wol(struct net_device *netdev, | ||
1270 | struct ethtool_wolinfo *wol) | ||
1271 | { | ||
1272 | if (0 <= ps3_compare_firmware_version(2, 2, 0)) | ||
1273 | wol->supported = WAKE_MAGIC; | ||
1274 | else | ||
1275 | wol->supported = 0; | ||
1276 | |||
1277 | wol->wolopts = ps3_sys_manager_get_wol() ? wol->supported : 0; | ||
1278 | memset(&wol->sopass, 0, sizeof(wol->sopass)); | ||
1279 | } | ||
1280 | static int gelic_net_set_wol(struct net_device *netdev, | ||
1281 | struct ethtool_wolinfo *wol) | ||
1282 | { | ||
1283 | int status; | ||
1284 | struct gelic_card *card; | ||
1285 | u64 v1, v2; | ||
1286 | |||
1287 | if (ps3_compare_firmware_version(2, 2, 0) < 0 || | ||
1288 | !capable(CAP_NET_ADMIN)) | ||
1289 | return -EPERM; | ||
1290 | |||
1291 | if (wol->wolopts & ~WAKE_MAGIC) | ||
1292 | return -EINVAL; | ||
1293 | |||
1294 | card = netdev_card(netdev); | ||
1295 | if (wol->wolopts & WAKE_MAGIC) { | ||
1296 | status = lv1_net_control(bus_id(card), dev_id(card), | ||
1297 | GELIC_LV1_SET_WOL, | ||
1298 | GELIC_LV1_WOL_MAGIC_PACKET, | ||
1299 | 0, GELIC_LV1_WOL_MP_ENABLE, | ||
1300 | &v1, &v2); | ||
1301 | if (status) { | ||
1302 | pr_info("%s: enabling WOL failed %d\n", __func__, | ||
1303 | status); | ||
1304 | status = -EIO; | ||
1305 | goto done; | ||
1306 | } | ||
1307 | status = lv1_net_control(bus_id(card), dev_id(card), | ||
1308 | GELIC_LV1_SET_WOL, | ||
1309 | GELIC_LV1_WOL_ADD_MATCH_ADDR, | ||
1310 | 0, GELIC_LV1_WOL_MATCH_ALL, | ||
1311 | &v1, &v2); | ||
1312 | if (!status) | ||
1313 | ps3_sys_manager_set_wol(1); | ||
1314 | else { | ||
1315 | pr_info("%s: enabling WOL filter failed %d\n", | ||
1316 | __func__, status); | ||
1317 | status = -EIO; | ||
1318 | } | ||
1319 | } else { | ||
1320 | status = lv1_net_control(bus_id(card), dev_id(card), | ||
1321 | GELIC_LV1_SET_WOL, | ||
1322 | GELIC_LV1_WOL_MAGIC_PACKET, | ||
1323 | 0, GELIC_LV1_WOL_MP_DISABLE, | ||
1324 | &v1, &v2); | ||
1325 | if (status) { | ||
1326 | pr_info("%s: disabling WOL failed %d\n", __func__, | ||
1327 | status); | ||
1328 | status = -EIO; | ||
1329 | goto done; | ||
1330 | } | ||
1331 | status = lv1_net_control(bus_id(card), dev_id(card), | ||
1332 | GELIC_LV1_SET_WOL, | ||
1333 | GELIC_LV1_WOL_DELETE_MATCH_ADDR, | ||
1334 | 0, GELIC_LV1_WOL_MATCH_ALL, | ||
1335 | &v1, &v2); | ||
1336 | if (!status) | ||
1337 | ps3_sys_manager_set_wol(0); | ||
1338 | else { | ||
1339 | pr_info("%s: removing WOL filter failed %d\n", | ||
1340 | __func__, status); | ||
1341 | status = -EIO; | ||
1342 | } | ||
1343 | } | ||
1344 | done: | ||
1345 | return status; | ||
1346 | } | ||
1347 | |||
1269 | static struct ethtool_ops gelic_ether_ethtool_ops = { | 1348 | static struct ethtool_ops gelic_ether_ethtool_ops = { |
1270 | .get_drvinfo = gelic_net_get_drvinfo, | 1349 | .get_drvinfo = gelic_net_get_drvinfo, |
1271 | .get_settings = gelic_ether_get_settings, | 1350 | .get_settings = gelic_ether_get_settings, |
@@ -1274,6 +1353,8 @@ static struct ethtool_ops gelic_ether_ethtool_ops = { | |||
1274 | .set_tx_csum = ethtool_op_set_tx_csum, | 1353 | .set_tx_csum = ethtool_op_set_tx_csum, |
1275 | .get_rx_csum = gelic_net_get_rx_csum, | 1354 | .get_rx_csum = gelic_net_get_rx_csum, |
1276 | .set_rx_csum = gelic_net_set_rx_csum, | 1355 | .set_rx_csum = gelic_net_set_rx_csum, |
1356 | .get_wol = gelic_net_get_wol, | ||
1357 | .set_wol = gelic_net_set_wol, | ||
1277 | }; | 1358 | }; |
1278 | 1359 | ||
1279 | /** | 1360 | /** |