diff options
Diffstat (limited to 'drivers/net/ps3_gelic_net.c')
-rw-r--r-- | drivers/net/ps3_gelic_net.c | 105 |
1 files changed, 87 insertions, 18 deletions
diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c index b211613e9dbd..5bf229bb34c2 100644 --- a/drivers/net/ps3_gelic_net.c +++ b/drivers/net/ps3_gelic_net.c | |||
@@ -30,6 +30,7 @@ | |||
30 | 30 | ||
31 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
33 | #include <linux/slab.h> | ||
33 | 34 | ||
34 | #include <linux/etherdevice.h> | 35 | #include <linux/etherdevice.h> |
35 | #include <linux/ethtool.h> | 36 | #include <linux/ethtool.h> |
@@ -95,11 +96,11 @@ static void gelic_card_get_ether_port_status(struct gelic_card *card, | |||
95 | 96 | ||
96 | lv1_net_control(bus_id(card), dev_id(card), | 97 | lv1_net_control(bus_id(card), dev_id(card), |
97 | GELIC_LV1_GET_ETH_PORT_STATUS, | 98 | GELIC_LV1_GET_ETH_PORT_STATUS, |
98 | GELIC_LV1_VLAN_TX_ETHERNET, 0, 0, | 99 | GELIC_LV1_VLAN_TX_ETHERNET_0, 0, 0, |
99 | &card->ether_port_status, &v2); | 100 | &card->ether_port_status, &v2); |
100 | 101 | ||
101 | if (inform) { | 102 | if (inform) { |
102 | ether_netdev = card->netdev[GELIC_PORT_ETHERNET]; | 103 | ether_netdev = card->netdev[GELIC_PORT_ETHERNET_0]; |
103 | if (card->ether_port_status & GELIC_LV1_ETHER_LINK_UP) | 104 | if (card->ether_port_status & GELIC_LV1_ETHER_LINK_UP) |
104 | netif_carrier_on(ether_netdev); | 105 | netif_carrier_on(ether_netdev); |
105 | else | 106 | else |
@@ -107,6 +108,24 @@ static void gelic_card_get_ether_port_status(struct gelic_card *card, | |||
107 | } | 108 | } |
108 | } | 109 | } |
109 | 110 | ||
111 | static int gelic_card_set_link_mode(struct gelic_card *card, int mode) | ||
112 | { | ||
113 | int status; | ||
114 | u64 v1, v2; | ||
115 | |||
116 | status = lv1_net_control(bus_id(card), dev_id(card), | ||
117 | GELIC_LV1_SET_NEGOTIATION_MODE, | ||
118 | GELIC_LV1_PHY_ETHERNET_0, mode, 0, &v1, &v2); | ||
119 | if (status) { | ||
120 | pr_info("%s: failed setting negotiation mode %d\n", __func__, | ||
121 | status); | ||
122 | return -EBUSY; | ||
123 | } | ||
124 | |||
125 | card->link_mode = mode; | ||
126 | return 0; | ||
127 | } | ||
128 | |||
110 | void gelic_card_up(struct gelic_card *card) | 129 | void gelic_card_up(struct gelic_card *card) |
111 | { | 130 | { |
112 | pr_debug("%s: called\n", __func__); | 131 | pr_debug("%s: called\n", __func__); |
@@ -296,7 +315,7 @@ static void gelic_card_reset_chain(struct gelic_card *card, | |||
296 | * @card: card structure | 315 | * @card: card structure |
297 | * @descr: descriptor to re-init | 316 | * @descr: descriptor to re-init |
298 | * | 317 | * |
299 | * return 0 on succes, <0 on failure | 318 | * return 0 on success, <0 on failure |
300 | * | 319 | * |
301 | * allocates a new rx skb, iommu-maps it and attaches it to the descriptor. | 320 | * allocates a new rx skb, iommu-maps it and attaches it to the descriptor. |
302 | * Activate the descriptor state-wise | 321 | * Activate the descriptor state-wise |
@@ -451,14 +470,14 @@ static void gelic_descr_release_tx(struct gelic_card *card, | |||
451 | 470 | ||
452 | static void gelic_card_stop_queues(struct gelic_card *card) | 471 | static void gelic_card_stop_queues(struct gelic_card *card) |
453 | { | 472 | { |
454 | netif_stop_queue(card->netdev[GELIC_PORT_ETHERNET]); | 473 | netif_stop_queue(card->netdev[GELIC_PORT_ETHERNET_0]); |
455 | 474 | ||
456 | if (card->netdev[GELIC_PORT_WIRELESS]) | 475 | if (card->netdev[GELIC_PORT_WIRELESS]) |
457 | netif_stop_queue(card->netdev[GELIC_PORT_WIRELESS]); | 476 | netif_stop_queue(card->netdev[GELIC_PORT_WIRELESS]); |
458 | } | 477 | } |
459 | static void gelic_card_wake_queues(struct gelic_card *card) | 478 | static void gelic_card_wake_queues(struct gelic_card *card) |
460 | { | 479 | { |
461 | netif_wake_queue(card->netdev[GELIC_PORT_ETHERNET]); | 480 | netif_wake_queue(card->netdev[GELIC_PORT_ETHERNET_0]); |
462 | 481 | ||
463 | if (card->netdev[GELIC_PORT_WIRELESS]) | 482 | if (card->netdev[GELIC_PORT_WIRELESS]) |
464 | netif_wake_queue(card->netdev[GELIC_PORT_WIRELESS]); | 483 | netif_wake_queue(card->netdev[GELIC_PORT_WIRELESS]); |
@@ -550,7 +569,7 @@ void gelic_net_set_multi(struct net_device *netdev) | |||
550 | status); | 569 | status); |
551 | 570 | ||
552 | if ((netdev->flags & IFF_ALLMULTI) || | 571 | if ((netdev->flags & IFF_ALLMULTI) || |
553 | (netdev->mc_count > GELIC_NET_MC_COUNT_MAX)) { | 572 | (netdev_mc_count(netdev) > GELIC_NET_MC_COUNT_MAX)) { |
554 | status = lv1_net_add_multicast_address(bus_id(card), | 573 | status = lv1_net_add_multicast_address(bus_id(card), |
555 | dev_id(card), | 574 | dev_id(card), |
556 | 0, 1); | 575 | 0, 1); |
@@ -562,7 +581,7 @@ void gelic_net_set_multi(struct net_device *netdev) | |||
562 | } | 581 | } |
563 | 582 | ||
564 | /* set multicast addresses */ | 583 | /* set multicast addresses */ |
565 | for (mc = netdev->mc_list; mc; mc = mc->next) { | 584 | netdev_for_each_mc_addr(mc, netdev) { |
566 | addr = 0; | 585 | addr = 0; |
567 | p = mc->dmi_addr; | 586 | p = mc->dmi_addr; |
568 | for (i = 0; i < ETH_ALEN; i++) { | 587 | for (i = 0; i < ETH_ALEN; i++) { |
@@ -999,7 +1018,7 @@ static int gelic_card_decode_one_descr(struct gelic_card *card) | |||
999 | goto refill; | 1018 | goto refill; |
1000 | } | 1019 | } |
1001 | } else | 1020 | } else |
1002 | netdev = card->netdev[GELIC_PORT_ETHERNET]; | 1021 | netdev = card->netdev[GELIC_PORT_ETHERNET_0]; |
1003 | 1022 | ||
1004 | if ((status == GELIC_DESCR_DMA_RESPONSE_ERROR) || | 1023 | if ((status == GELIC_DESCR_DMA_RESPONSE_ERROR) || |
1005 | (status == GELIC_DESCR_DMA_PROTECTION_ERROR) || | 1024 | (status == GELIC_DESCR_DMA_PROTECTION_ERROR) || |
@@ -1244,14 +1263,58 @@ static int gelic_ether_get_settings(struct net_device *netdev, | |||
1244 | cmd->supported = SUPPORTED_TP | SUPPORTED_Autoneg | | 1263 | cmd->supported = SUPPORTED_TP | SUPPORTED_Autoneg | |
1245 | SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | | 1264 | SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | |
1246 | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | | 1265 | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | |
1247 | SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full; | 1266 | SUPPORTED_1000baseT_Full; |
1248 | cmd->advertising = cmd->supported; | 1267 | cmd->advertising = cmd->supported; |
1249 | cmd->autoneg = AUTONEG_ENABLE; /* always enabled */ | 1268 | if (card->link_mode & GELIC_LV1_ETHER_AUTO_NEG) { |
1269 | cmd->autoneg = AUTONEG_ENABLE; | ||
1270 | } else { | ||
1271 | cmd->autoneg = AUTONEG_DISABLE; | ||
1272 | cmd->advertising &= ~ADVERTISED_Autoneg; | ||
1273 | } | ||
1250 | cmd->port = PORT_TP; | 1274 | cmd->port = PORT_TP; |
1251 | 1275 | ||
1252 | return 0; | 1276 | return 0; |
1253 | } | 1277 | } |
1254 | 1278 | ||
1279 | static int gelic_ether_set_settings(struct net_device *netdev, | ||
1280 | struct ethtool_cmd *cmd) | ||
1281 | { | ||
1282 | struct gelic_card *card = netdev_card(netdev); | ||
1283 | u64 mode; | ||
1284 | int ret; | ||
1285 | |||
1286 | if (cmd->autoneg == AUTONEG_ENABLE) { | ||
1287 | mode = GELIC_LV1_ETHER_AUTO_NEG; | ||
1288 | } else { | ||
1289 | switch (cmd->speed) { | ||
1290 | case SPEED_10: | ||
1291 | mode = GELIC_LV1_ETHER_SPEED_10; | ||
1292 | break; | ||
1293 | case SPEED_100: | ||
1294 | mode = GELIC_LV1_ETHER_SPEED_100; | ||
1295 | break; | ||
1296 | case SPEED_1000: | ||
1297 | mode = GELIC_LV1_ETHER_SPEED_1000; | ||
1298 | break; | ||
1299 | default: | ||
1300 | return -EINVAL; | ||
1301 | } | ||
1302 | if (cmd->duplex == DUPLEX_FULL) | ||
1303 | mode |= GELIC_LV1_ETHER_FULL_DUPLEX; | ||
1304 | else if (cmd->speed == SPEED_1000) { | ||
1305 | pr_info("1000 half duplex is not supported.\n"); | ||
1306 | return -EINVAL; | ||
1307 | } | ||
1308 | } | ||
1309 | |||
1310 | ret = gelic_card_set_link_mode(card, mode); | ||
1311 | |||
1312 | if (ret) | ||
1313 | return ret; | ||
1314 | |||
1315 | return 0; | ||
1316 | } | ||
1317 | |||
1255 | u32 gelic_net_get_rx_csum(struct net_device *netdev) | 1318 | u32 gelic_net_get_rx_csum(struct net_device *netdev) |
1256 | { | 1319 | { |
1257 | struct gelic_card *card = netdev_card(netdev); | 1320 | struct gelic_card *card = netdev_card(netdev); |
@@ -1349,6 +1412,7 @@ done: | |||
1349 | static const struct ethtool_ops gelic_ether_ethtool_ops = { | 1412 | static const struct ethtool_ops gelic_ether_ethtool_ops = { |
1350 | .get_drvinfo = gelic_net_get_drvinfo, | 1413 | .get_drvinfo = gelic_net_get_drvinfo, |
1351 | .get_settings = gelic_ether_get_settings, | 1414 | .get_settings = gelic_ether_get_settings, |
1415 | .set_settings = gelic_ether_set_settings, | ||
1352 | .get_link = ethtool_op_get_link, | 1416 | .get_link = ethtool_op_get_link, |
1353 | .get_tx_csum = ethtool_op_get_tx_csum, | 1417 | .get_tx_csum = ethtool_op_get_tx_csum, |
1354 | .set_tx_csum = ethtool_op_set_tx_csum, | 1418 | .set_tx_csum = ethtool_op_set_tx_csum, |
@@ -1369,7 +1433,7 @@ static void gelic_net_tx_timeout_task(struct work_struct *work) | |||
1369 | { | 1433 | { |
1370 | struct gelic_card *card = | 1434 | struct gelic_card *card = |
1371 | container_of(work, struct gelic_card, tx_timeout_task); | 1435 | container_of(work, struct gelic_card, tx_timeout_task); |
1372 | struct net_device *netdev = card->netdev[GELIC_PORT_ETHERNET]; | 1436 | struct net_device *netdev = card->netdev[GELIC_PORT_ETHERNET_0]; |
1373 | 1437 | ||
1374 | dev_info(ctodev(card), "%s:Timed out. Restarting... \n", __func__); | 1438 | dev_info(ctodev(card), "%s:Timed out. Restarting... \n", __func__); |
1375 | 1439 | ||
@@ -1531,10 +1595,10 @@ static struct gelic_card * __devinit gelic_alloc_card_net(struct net_device **ne | |||
1531 | /* gelic_port */ | 1595 | /* gelic_port */ |
1532 | port->netdev = *netdev; | 1596 | port->netdev = *netdev; |
1533 | port->card = card; | 1597 | port->card = card; |
1534 | port->type = GELIC_PORT_ETHERNET; | 1598 | port->type = GELIC_PORT_ETHERNET_0; |
1535 | 1599 | ||
1536 | /* gelic_card */ | 1600 | /* gelic_card */ |
1537 | card->netdev[GELIC_PORT_ETHERNET] = *netdev; | 1601 | card->netdev[GELIC_PORT_ETHERNET_0] = *netdev; |
1538 | 1602 | ||
1539 | INIT_WORK(&card->tx_timeout_task, gelic_net_tx_timeout_task); | 1603 | INIT_WORK(&card->tx_timeout_task, gelic_net_tx_timeout_task); |
1540 | init_waitqueue_head(&card->waitq); | 1604 | init_waitqueue_head(&card->waitq); |
@@ -1554,9 +1618,9 @@ static void __devinit gelic_card_get_vlan_info(struct gelic_card *card) | |||
1554 | int tx; | 1618 | int tx; |
1555 | int rx; | 1619 | int rx; |
1556 | } vlan_id_ix[2] = { | 1620 | } vlan_id_ix[2] = { |
1557 | [GELIC_PORT_ETHERNET] = { | 1621 | [GELIC_PORT_ETHERNET_0] = { |
1558 | .tx = GELIC_LV1_VLAN_TX_ETHERNET, | 1622 | .tx = GELIC_LV1_VLAN_TX_ETHERNET_0, |
1559 | .rx = GELIC_LV1_VLAN_RX_ETHERNET | 1623 | .rx = GELIC_LV1_VLAN_RX_ETHERNET_0 |
1560 | }, | 1624 | }, |
1561 | [GELIC_PORT_WIRELESS] = { | 1625 | [GELIC_PORT_WIRELESS] = { |
1562 | .tx = GELIC_LV1_VLAN_TX_WIRELESS, | 1626 | .tx = GELIC_LV1_VLAN_TX_WIRELESS, |
@@ -1601,7 +1665,7 @@ static void __devinit gelic_card_get_vlan_info(struct gelic_card *card) | |||
1601 | i, card->vlan[i].tx, card->vlan[i].rx); | 1665 | i, card->vlan[i].tx, card->vlan[i].rx); |
1602 | } | 1666 | } |
1603 | 1667 | ||
1604 | if (card->vlan[GELIC_PORT_ETHERNET].tx) { | 1668 | if (card->vlan[GELIC_PORT_ETHERNET_0].tx) { |
1605 | BUG_ON(!card->vlan[GELIC_PORT_WIRELESS].tx); | 1669 | BUG_ON(!card->vlan[GELIC_PORT_WIRELESS].tx); |
1606 | card->vlan_required = 1; | 1670 | card->vlan_required = 1; |
1607 | } else | 1671 | } else |
@@ -1657,6 +1721,8 @@ static int __devinit ps3_gelic_driver_probe(struct ps3_system_bus_device *dev) | |||
1657 | /* get internal vlan info */ | 1721 | /* get internal vlan info */ |
1658 | gelic_card_get_vlan_info(card); | 1722 | gelic_card_get_vlan_info(card); |
1659 | 1723 | ||
1724 | card->link_mode = GELIC_LV1_ETHER_AUTO_NEG; | ||
1725 | |||
1660 | /* setup interrupt */ | 1726 | /* setup interrupt */ |
1661 | result = lv1_net_set_interrupt_status_indicator(bus_id(card), | 1727 | result = lv1_net_set_interrupt_status_indicator(bus_id(card), |
1662 | dev_id(card), | 1728 | dev_id(card), |
@@ -1773,6 +1839,9 @@ static int ps3_gelic_driver_remove(struct ps3_system_bus_device *dev) | |||
1773 | struct net_device *netdev0; | 1839 | struct net_device *netdev0; |
1774 | pr_debug("%s: called\n", __func__); | 1840 | pr_debug("%s: called\n", __func__); |
1775 | 1841 | ||
1842 | /* set auto-negotiation */ | ||
1843 | gelic_card_set_link_mode(card, GELIC_LV1_ETHER_AUTO_NEG); | ||
1844 | |||
1776 | #ifdef CONFIG_GELIC_WIRELESS | 1845 | #ifdef CONFIG_GELIC_WIRELESS |
1777 | gelic_wl_driver_remove(card); | 1846 | gelic_wl_driver_remove(card); |
1778 | #endif | 1847 | #endif |
@@ -1790,7 +1859,7 @@ static int ps3_gelic_driver_remove(struct ps3_system_bus_device *dev) | |||
1790 | gelic_card_free_chain(card, card->tx_top); | 1859 | gelic_card_free_chain(card, card->tx_top); |
1791 | gelic_card_free_chain(card, card->rx_top); | 1860 | gelic_card_free_chain(card, card->rx_top); |
1792 | 1861 | ||
1793 | netdev0 = card->netdev[GELIC_PORT_ETHERNET]; | 1862 | netdev0 = card->netdev[GELIC_PORT_ETHERNET_0]; |
1794 | /* disconnect event port */ | 1863 | /* disconnect event port */ |
1795 | free_irq(card->irq, card); | 1864 | free_irq(card->irq, card); |
1796 | netdev0->irq = NO_IRQ; | 1865 | netdev0->irq = NO_IRQ; |