diff options
author | Masakazu Mokuno <mokuno@sm.sony.co.jp> | 2008-02-07 05:58:32 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2008-02-11 10:29:52 -0500 |
commit | 01fed4c284def58b8a9ee0b915c3956b93c670b7 (patch) | |
tree | 830ddb0858e83ee2c716bb9b7a0de40858d7f95f /drivers/net/ps3_gelic_net.c | |
parent | 7bc56b92b025c13f8d3c9b049ed816db464fb0b5 (diff) |
PS3: gelic: add support for port link status
Add support for interrupt driven port link status detection.
Signed-off-by: Masakazu Mokuno <mokuno@sm.sony.co.jp>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/ps3_gelic_net.c')
-rw-r--r-- | drivers/net/ps3_gelic_net.c | 77 |
1 files changed, 50 insertions, 27 deletions
diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c index 87fc3b765e8e..3b11b1ca0e77 100644 --- a/drivers/net/ps3_gelic_net.c +++ b/drivers/net/ps3_gelic_net.c | |||
@@ -87,6 +87,28 @@ static inline void gelic_card_rx_irq_off(struct gelic_card *card) | |||
87 | { | 87 | { |
88 | gelic_card_set_irq_mask(card, card->ghiintmask & ~GELIC_CARD_RXINT); | 88 | gelic_card_set_irq_mask(card, card->ghiintmask & ~GELIC_CARD_RXINT); |
89 | } | 89 | } |
90 | |||
91 | static void | ||
92 | gelic_card_get_ether_port_status(struct gelic_card *card, int inform) | ||
93 | { | ||
94 | u64 v2; | ||
95 | struct net_device *ether_netdev; | ||
96 | |||
97 | lv1_net_control(bus_id(card), dev_id(card), | ||
98 | GELIC_LV1_GET_ETH_PORT_STATUS, | ||
99 | GELIC_LV1_VLAN_TX_ETHERNET, 0, 0, | ||
100 | &card->ether_port_status, &v2); | ||
101 | |||
102 | if (inform) { | ||
103 | ether_netdev = card->netdev; | ||
104 | if (card->ether_port_status & GELIC_LV1_ETHER_LINK_UP) | ||
105 | netif_carrier_on(ether_netdev); | ||
106 | else | ||
107 | netif_carrier_off(ether_netdev); | ||
108 | } | ||
109 | } | ||
110 | |||
111 | |||
90 | /** | 112 | /** |
91 | * gelic_descr_get_status -- returns the status of a descriptor | 113 | * gelic_descr_get_status -- returns the status of a descriptor |
92 | * @descr: descriptor to look at | 114 | * @descr: descriptor to look at |
@@ -1032,6 +1054,10 @@ static irqreturn_t gelic_card_interrupt(int irq, void *ptr) | |||
1032 | gelic_card_kick_txdma(card, card->tx_chain.tail); | 1054 | gelic_card_kick_txdma(card, card->tx_chain.tail); |
1033 | spin_unlock_irqrestore(&card->tx_dma_lock, flags); | 1055 | spin_unlock_irqrestore(&card->tx_dma_lock, flags); |
1034 | } | 1056 | } |
1057 | |||
1058 | /* ether port status changed */ | ||
1059 | if (status & GELIC_CARD_PORT_STATUS_CHANGED) | ||
1060 | gelic_card_get_ether_port_status(card, 1); | ||
1035 | return IRQ_HANDLED; | 1061 | return IRQ_HANDLED; |
1036 | } | 1062 | } |
1037 | 1063 | ||
@@ -1128,13 +1154,14 @@ static int gelic_net_open(struct net_device *netdev) | |||
1128 | napi_enable(&card->napi); | 1154 | napi_enable(&card->napi); |
1129 | 1155 | ||
1130 | card->tx_dma_progress = 0; | 1156 | card->tx_dma_progress = 0; |
1131 | card->ghiintmask = GELIC_CARD_RXINT | GELIC_CARD_TXINT; | 1157 | card->ghiintmask = GELIC_CARD_RXINT | GELIC_CARD_TXINT | |
1158 | GELIC_CARD_PORT_STATUS_CHANGED; | ||
1132 | 1159 | ||
1133 | gelic_card_set_irq_mask(card, card->ghiintmask); | 1160 | gelic_card_set_irq_mask(card, card->ghiintmask); |
1134 | gelic_card_enable_rxdmac(card); | 1161 | gelic_card_enable_rxdmac(card); |
1135 | 1162 | ||
1136 | netif_start_queue(netdev); | 1163 | netif_start_queue(netdev); |
1137 | netif_carrier_on(netdev); | 1164 | gelic_card_get_ether_port_status(card, 1); |
1138 | 1165 | ||
1139 | return 0; | 1166 | return 0; |
1140 | 1167 | ||
@@ -1157,39 +1184,35 @@ static int gelic_ether_get_settings(struct net_device *netdev, | |||
1157 | struct ethtool_cmd *cmd) | 1184 | struct ethtool_cmd *cmd) |
1158 | { | 1185 | { |
1159 | struct gelic_card *card = netdev_priv(netdev); | 1186 | struct gelic_card *card = netdev_priv(netdev); |
1160 | int status; | ||
1161 | u64 v1, v2; | ||
1162 | int speed, duplex; | ||
1163 | 1187 | ||
1164 | speed = duplex = -1; | 1188 | gelic_card_get_ether_port_status(card, 0); |
1165 | status = lv1_net_control(bus_id(card), dev_id(card), | ||
1166 | GELIC_LV1_GET_ETH_PORT_STATUS, | ||
1167 | GELIC_LV1_VLAN_TX_ETHERNET, 0, 0, | ||
1168 | &v1, &v2); | ||
1169 | if (status) { | ||
1170 | /* link down */ | ||
1171 | } else { | ||
1172 | if (v1 & GELIC_LV1_ETHER_FULL_DUPLEX) { | ||
1173 | duplex = DUPLEX_FULL; | ||
1174 | } else { | ||
1175 | duplex = DUPLEX_HALF; | ||
1176 | } | ||
1177 | 1189 | ||
1178 | if (v1 & GELIC_LV1_ETHER_SPEED_10) { | 1190 | if (card->ether_port_status & GELIC_LV1_ETHER_FULL_DUPLEX) |
1179 | speed = SPEED_10; | 1191 | cmd->duplex = DUPLEX_FULL; |
1180 | } else if (v1 & GELIC_LV1_ETHER_SPEED_100) { | 1192 | else |
1181 | speed = SPEED_100; | 1193 | cmd->duplex = DUPLEX_HALF; |
1182 | } else if (v1 & GELIC_LV1_ETHER_SPEED_1000) { | 1194 | |
1183 | speed = SPEED_1000; | 1195 | switch (card->ether_port_status & GELIC_LV1_ETHER_SPEED_MASK) { |
1184 | } | 1196 | case GELIC_LV1_ETHER_SPEED_10: |
1197 | cmd->speed = SPEED_10; | ||
1198 | break; | ||
1199 | case GELIC_LV1_ETHER_SPEED_100: | ||
1200 | cmd->speed = SPEED_100; | ||
1201 | break; | ||
1202 | case GELIC_LV1_ETHER_SPEED_1000: | ||
1203 | cmd->speed = SPEED_1000; | ||
1204 | break; | ||
1205 | default: | ||
1206 | pr_info("%s: speed unknown\n", __func__); | ||
1207 | cmd->speed = SPEED_10; | ||
1208 | break; | ||
1185 | } | 1209 | } |
1210 | |||
1186 | cmd->supported = SUPPORTED_TP | SUPPORTED_Autoneg | | 1211 | cmd->supported = SUPPORTED_TP | SUPPORTED_Autoneg | |
1187 | SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | | 1212 | SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | |
1188 | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | | 1213 | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | |
1189 | SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full; | 1214 | SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full; |
1190 | cmd->advertising = cmd->supported; | 1215 | cmd->advertising = cmd->supported; |
1191 | cmd->speed = speed; | ||
1192 | cmd->duplex = duplex; | ||
1193 | cmd->autoneg = AUTONEG_ENABLE; /* always enabled */ | 1216 | cmd->autoneg = AUTONEG_ENABLE; /* always enabled */ |
1194 | cmd->port = PORT_TP; | 1217 | cmd->port = PORT_TP; |
1195 | 1218 | ||