diff options
author | Michał Mirosław <mirq-linux@rere.qmqm.pl> | 2011-04-09 23:13:21 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-04-12 17:50:42 -0400 |
commit | f5d640371dacda100a32a30e8013f957aff26ce1 (patch) | |
tree | 58bd3509c4d4a2026f2607fc65ea174b8aad83d2 | |
parent | 872674858fe236b746317741013c830bb70775c2 (diff) |
net: sky2: convert to hw_features
Caveats:
- driver modifies vlan_features on HW VLAN TX changes
- broken RX checksum will be reenabled on features change
Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/sky2.c | 161 | ||||
-rw-r--r-- | drivers/net/sky2.h | 1 |
2 files changed, 59 insertions, 103 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 336c762515b2..a4b8fe564eb0 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -1198,12 +1198,12 @@ static void rx_set_checksum(struct sky2_port *sky2) | |||
1198 | 1198 | ||
1199 | sky2_write32(sky2->hw, | 1199 | sky2_write32(sky2->hw, |
1200 | Q_ADDR(rxqaddr[sky2->port], Q_CSR), | 1200 | Q_ADDR(rxqaddr[sky2->port], Q_CSR), |
1201 | (sky2->flags & SKY2_FLAG_RX_CHECKSUM) | 1201 | (sky2->netdev->features & NETIF_F_RXCSUM) |
1202 | ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); | 1202 | ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); |
1203 | } | 1203 | } |
1204 | 1204 | ||
1205 | /* Enable/disable receive hash calculation (RSS) */ | 1205 | /* Enable/disable receive hash calculation (RSS) */ |
1206 | static void rx_set_rss(struct net_device *dev) | 1206 | static void rx_set_rss(struct net_device *dev, u32 features) |
1207 | { | 1207 | { |
1208 | struct sky2_port *sky2 = netdev_priv(dev); | 1208 | struct sky2_port *sky2 = netdev_priv(dev); |
1209 | struct sky2_hw *hw = sky2->hw; | 1209 | struct sky2_hw *hw = sky2->hw; |
@@ -1216,7 +1216,7 @@ static void rx_set_rss(struct net_device *dev) | |||
1216 | } | 1216 | } |
1217 | 1217 | ||
1218 | /* Program RSS initial values */ | 1218 | /* Program RSS initial values */ |
1219 | if (dev->features & NETIF_F_RXHASH) { | 1219 | if (features & NETIF_F_RXHASH) { |
1220 | u32 key[nkeys]; | 1220 | u32 key[nkeys]; |
1221 | 1221 | ||
1222 | get_random_bytes(key, nkeys * sizeof(u32)); | 1222 | get_random_bytes(key, nkeys * sizeof(u32)); |
@@ -1322,32 +1322,32 @@ static int sky2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
1322 | return err; | 1322 | return err; |
1323 | } | 1323 | } |
1324 | 1324 | ||
1325 | #define NETIF_F_ALL_VLAN (NETIF_F_HW_VLAN_TX|NETIF_F_HW_VLAN_RX) | 1325 | #define SKY2_VLAN_OFFLOADS (NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO) |
1326 | 1326 | ||
1327 | static void sky2_vlan_mode(struct net_device *dev) | 1327 | static void sky2_vlan_mode(struct net_device *dev, u32 features) |
1328 | { | 1328 | { |
1329 | struct sky2_port *sky2 = netdev_priv(dev); | 1329 | struct sky2_port *sky2 = netdev_priv(dev); |
1330 | struct sky2_hw *hw = sky2->hw; | 1330 | struct sky2_hw *hw = sky2->hw; |
1331 | u16 port = sky2->port; | 1331 | u16 port = sky2->port; |
1332 | 1332 | ||
1333 | if (dev->features & NETIF_F_HW_VLAN_RX) | 1333 | if (features & NETIF_F_HW_VLAN_RX) |
1334 | sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), | 1334 | sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), |
1335 | RX_VLAN_STRIP_ON); | 1335 | RX_VLAN_STRIP_ON); |
1336 | else | 1336 | else |
1337 | sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), | 1337 | sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), |
1338 | RX_VLAN_STRIP_OFF); | 1338 | RX_VLAN_STRIP_OFF); |
1339 | 1339 | ||
1340 | dev->vlan_features = dev->features &~ NETIF_F_ALL_VLAN; | 1340 | if (features & NETIF_F_HW_VLAN_TX) { |
1341 | if (dev->features & NETIF_F_HW_VLAN_TX) | ||
1342 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), | 1341 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), |
1343 | TX_VLAN_TAG_ON); | 1342 | TX_VLAN_TAG_ON); |
1344 | else { | 1343 | |
1344 | dev->vlan_features |= SKY2_VLAN_OFFLOADS; | ||
1345 | } else { | ||
1345 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), | 1346 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), |
1346 | TX_VLAN_TAG_OFF); | 1347 | TX_VLAN_TAG_OFF); |
1347 | 1348 | ||
1348 | /* Can't do transmit offload of vlan without hw vlan */ | 1349 | /* Can't do transmit offload of vlan without hw vlan */ |
1349 | dev->vlan_features &= ~(NETIF_F_TSO | NETIF_F_SG | 1350 | dev->vlan_features &= ~SKY2_VLAN_OFFLOADS; |
1350 | | NETIF_F_ALL_CSUM); | ||
1351 | } | 1351 | } |
1352 | } | 1352 | } |
1353 | 1353 | ||
@@ -1463,7 +1463,7 @@ static void sky2_rx_start(struct sky2_port *sky2) | |||
1463 | rx_set_checksum(sky2); | 1463 | rx_set_checksum(sky2); |
1464 | 1464 | ||
1465 | if (!(hw->flags & SKY2_HW_RSS_BROKEN)) | 1465 | if (!(hw->flags & SKY2_HW_RSS_BROKEN)) |
1466 | rx_set_rss(sky2->netdev); | 1466 | rx_set_rss(sky2->netdev, sky2->netdev->features); |
1467 | 1467 | ||
1468 | /* submit Rx ring */ | 1468 | /* submit Rx ring */ |
1469 | for (i = 0; i < sky2->rx_pending; i++) { | 1469 | for (i = 0; i < sky2->rx_pending; i++) { |
@@ -1626,7 +1626,8 @@ static void sky2_hw_up(struct sky2_port *sky2) | |||
1626 | sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map, | 1626 | sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map, |
1627 | sky2->tx_ring_size - 1); | 1627 | sky2->tx_ring_size - 1); |
1628 | 1628 | ||
1629 | sky2_vlan_mode(sky2->netdev); | 1629 | sky2_vlan_mode(sky2->netdev, sky2->netdev->features); |
1630 | netdev_update_features(sky2->netdev); | ||
1630 | 1631 | ||
1631 | sky2_rx_start(sky2); | 1632 | sky2_rx_start(sky2); |
1632 | } | 1633 | } |
@@ -2261,12 +2262,9 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) | |||
2261 | hw->chip_id == CHIP_ID_YUKON_FE_P)) | 2262 | hw->chip_id == CHIP_ID_YUKON_FE_P)) |
2262 | return -EINVAL; | 2263 | return -EINVAL; |
2263 | 2264 | ||
2264 | /* TSO, etc on Yukon Ultra and MTU > 1500 not supported */ | ||
2265 | if (new_mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_EC_U) | ||
2266 | dev->features &= ~(NETIF_F_TSO|NETIF_F_SG|NETIF_F_ALL_CSUM); | ||
2267 | |||
2268 | if (!netif_running(dev)) { | 2265 | if (!netif_running(dev)) { |
2269 | dev->mtu = new_mtu; | 2266 | dev->mtu = new_mtu; |
2267 | netdev_update_features(dev); | ||
2270 | return 0; | 2268 | return 0; |
2271 | } | 2269 | } |
2272 | 2270 | ||
@@ -2288,6 +2286,7 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) | |||
2288 | sky2_rx_clean(sky2); | 2286 | sky2_rx_clean(sky2); |
2289 | 2287 | ||
2290 | dev->mtu = new_mtu; | 2288 | dev->mtu = new_mtu; |
2289 | netdev_update_features(dev); | ||
2291 | 2290 | ||
2292 | mode = DATA_BLIND_VAL(DATA_BLIND_DEF) | | 2291 | mode = DATA_BLIND_VAL(DATA_BLIND_DEF) | |
2293 | GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF); | 2292 | GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF); |
@@ -2535,8 +2534,11 @@ static void sky2_rx_checksum(struct sky2_port *sky2, u32 status) | |||
2535 | "%s: receive checksum problem (status = %#x)\n", | 2534 | "%s: receive checksum problem (status = %#x)\n", |
2536 | sky2->netdev->name, status); | 2535 | sky2->netdev->name, status); |
2537 | 2536 | ||
2538 | /* Disable checksum offload */ | 2537 | /* Disable checksum offload |
2539 | sky2->flags &= ~SKY2_FLAG_RX_CHECKSUM; | 2538 | * It will be reenabled on next ndo_set_features, but if it's |
2539 | * really broken, will get disabled again | ||
2540 | */ | ||
2541 | sky2->netdev->features &= ~NETIF_F_RXCSUM; | ||
2540 | sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR), | 2542 | sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR), |
2541 | BMU_DIS_RX_CHKSUM); | 2543 | BMU_DIS_RX_CHKSUM); |
2542 | } | 2544 | } |
@@ -2591,7 +2593,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) | |||
2591 | 2593 | ||
2592 | /* This chip reports checksum status differently */ | 2594 | /* This chip reports checksum status differently */ |
2593 | if (hw->flags & SKY2_HW_NEW_LE) { | 2595 | if (hw->flags & SKY2_HW_NEW_LE) { |
2594 | if ((sky2->flags & SKY2_FLAG_RX_CHECKSUM) && | 2596 | if ((dev->features & NETIF_F_RXCSUM) && |
2595 | (le->css & (CSS_ISIPV4 | CSS_ISIPV6)) && | 2597 | (le->css & (CSS_ISIPV4 | CSS_ISIPV6)) && |
2596 | (le->css & CSS_TCPUDPCSOK)) | 2598 | (le->css & CSS_TCPUDPCSOK)) |
2597 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 2599 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
@@ -2616,7 +2618,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) | |||
2616 | sky2->rx_tag = length; | 2618 | sky2->rx_tag = length; |
2617 | /* fall through */ | 2619 | /* fall through */ |
2618 | case OP_RXCHKS: | 2620 | case OP_RXCHKS: |
2619 | if (likely(sky2->flags & SKY2_FLAG_RX_CHECKSUM)) | 2621 | if (likely(dev->features & NETIF_F_RXCSUM)) |
2620 | sky2_rx_checksum(sky2, status); | 2622 | sky2_rx_checksum(sky2, status); |
2621 | break; | 2623 | break; |
2622 | 2624 | ||
@@ -3552,28 +3554,6 @@ static const struct sky2_stat { | |||
3552 | { "tx_fifo_underrun", GM_TXE_FIFO_UR }, | 3554 | { "tx_fifo_underrun", GM_TXE_FIFO_UR }, |
3553 | }; | 3555 | }; |
3554 | 3556 | ||
3555 | static u32 sky2_get_rx_csum(struct net_device *dev) | ||
3556 | { | ||
3557 | struct sky2_port *sky2 = netdev_priv(dev); | ||
3558 | |||
3559 | return !!(sky2->flags & SKY2_FLAG_RX_CHECKSUM); | ||
3560 | } | ||
3561 | |||
3562 | static int sky2_set_rx_csum(struct net_device *dev, u32 data) | ||
3563 | { | ||
3564 | struct sky2_port *sky2 = netdev_priv(dev); | ||
3565 | |||
3566 | if (data) | ||
3567 | sky2->flags |= SKY2_FLAG_RX_CHECKSUM; | ||
3568 | else | ||
3569 | sky2->flags &= ~SKY2_FLAG_RX_CHECKSUM; | ||
3570 | |||
3571 | sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR), | ||
3572 | data ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); | ||
3573 | |||
3574 | return 0; | ||
3575 | } | ||
3576 | |||
3577 | static u32 sky2_get_msglevel(struct net_device *netdev) | 3557 | static u32 sky2_get_msglevel(struct net_device *netdev) |
3578 | { | 3558 | { |
3579 | struct sky2_port *sky2 = netdev_priv(netdev); | 3559 | struct sky2_port *sky2 = netdev_priv(netdev); |
@@ -4084,34 +4064,6 @@ static void sky2_get_regs(struct net_device *dev, struct ethtool_regs *regs, | |||
4084 | } | 4064 | } |
4085 | } | 4065 | } |
4086 | 4066 | ||
4087 | /* In order to do Jumbo packets on these chips, need to turn off the | ||
4088 | * transmit store/forward. Therefore checksum offload won't work. | ||
4089 | */ | ||
4090 | static int no_tx_offload(struct net_device *dev) | ||
4091 | { | ||
4092 | const struct sky2_port *sky2 = netdev_priv(dev); | ||
4093 | const struct sky2_hw *hw = sky2->hw; | ||
4094 | |||
4095 | return dev->mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_EC_U; | ||
4096 | } | ||
4097 | |||
4098 | static int sky2_set_tx_csum(struct net_device *dev, u32 data) | ||
4099 | { | ||
4100 | if (data && no_tx_offload(dev)) | ||
4101 | return -EINVAL; | ||
4102 | |||
4103 | return ethtool_op_set_tx_csum(dev, data); | ||
4104 | } | ||
4105 | |||
4106 | |||
4107 | static int sky2_set_tso(struct net_device *dev, u32 data) | ||
4108 | { | ||
4109 | if (data && no_tx_offload(dev)) | ||
4110 | return -EINVAL; | ||
4111 | |||
4112 | return ethtool_op_set_tso(dev, data); | ||
4113 | } | ||
4114 | |||
4115 | static int sky2_get_eeprom_len(struct net_device *dev) | 4067 | static int sky2_get_eeprom_len(struct net_device *dev) |
4116 | { | 4068 | { |
4117 | struct sky2_port *sky2 = netdev_priv(dev); | 4069 | struct sky2_port *sky2 = netdev_priv(dev); |
@@ -4214,31 +4166,36 @@ static int sky2_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom | |||
4214 | return sky2_vpd_write(sky2->hw, cap, data, eeprom->offset, eeprom->len); | 4166 | return sky2_vpd_write(sky2->hw, cap, data, eeprom->offset, eeprom->len); |
4215 | } | 4167 | } |
4216 | 4168 | ||
4217 | static int sky2_set_flags(struct net_device *dev, u32 data) | 4169 | static u32 sky2_fix_features(struct net_device *dev, u32 features) |
4218 | { | 4170 | { |
4219 | struct sky2_port *sky2 = netdev_priv(dev); | 4171 | const struct sky2_port *sky2 = netdev_priv(dev); |
4220 | unsigned long old_feat = dev->features; | 4172 | const struct sky2_hw *hw = sky2->hw; |
4221 | u32 supported = 0; | ||
4222 | int rc; | ||
4223 | 4173 | ||
4224 | if (!(sky2->hw->flags & SKY2_HW_RSS_BROKEN)) | 4174 | /* In order to do Jumbo packets on these chips, need to turn off the |
4225 | supported |= ETH_FLAG_RXHASH; | 4175 | * transmit store/forward. Therefore checksum offload won't work. |
4176 | */ | ||
4177 | if (dev->mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_EC_U) | ||
4178 | features &= ~(NETIF_F_TSO|NETIF_F_SG|NETIF_F_ALL_CSUM); | ||
4226 | 4179 | ||
4227 | if (!(sky2->hw->flags & SKY2_HW_VLAN_BROKEN)) | 4180 | return features; |
4228 | supported |= ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN; | 4181 | } |
4229 | 4182 | ||
4230 | printk(KERN_DEBUG "sky2 set_flags: supported %x data %x\n", | 4183 | static int sky2_set_features(struct net_device *dev, u32 features) |
4231 | supported, data); | 4184 | { |
4185 | struct sky2_port *sky2 = netdev_priv(dev); | ||
4186 | u32 changed = dev->features ^ features; | ||
4232 | 4187 | ||
4233 | rc = ethtool_op_set_flags(dev, data, supported); | 4188 | if (changed & NETIF_F_RXCSUM) { |
4234 | if (rc) | 4189 | u32 on = features & NETIF_F_RXCSUM; |
4235 | return rc; | 4190 | sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR), |
4191 | on ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); | ||
4192 | } | ||
4236 | 4193 | ||
4237 | if ((old_feat ^ dev->features) & NETIF_F_RXHASH) | 4194 | if (changed & NETIF_F_RXHASH) |
4238 | rx_set_rss(dev); | 4195 | rx_set_rss(dev, features); |
4239 | 4196 | ||
4240 | if ((old_feat ^ dev->features) & NETIF_F_ALL_VLAN) | 4197 | if (changed & (NETIF_F_HW_VLAN_TX|NETIF_F_HW_VLAN_RX)) |
4241 | sky2_vlan_mode(dev); | 4198 | sky2_vlan_mode(dev, features); |
4242 | 4199 | ||
4243 | return 0; | 4200 | return 0; |
4244 | } | 4201 | } |
@@ -4258,11 +4215,6 @@ static const struct ethtool_ops sky2_ethtool_ops = { | |||
4258 | .get_eeprom_len = sky2_get_eeprom_len, | 4215 | .get_eeprom_len = sky2_get_eeprom_len, |
4259 | .get_eeprom = sky2_get_eeprom, | 4216 | .get_eeprom = sky2_get_eeprom, |
4260 | .set_eeprom = sky2_set_eeprom, | 4217 | .set_eeprom = sky2_set_eeprom, |
4261 | .set_sg = ethtool_op_set_sg, | ||
4262 | .set_tx_csum = sky2_set_tx_csum, | ||
4263 | .set_tso = sky2_set_tso, | ||
4264 | .get_rx_csum = sky2_get_rx_csum, | ||
4265 | .set_rx_csum = sky2_set_rx_csum, | ||
4266 | .get_strings = sky2_get_strings, | 4218 | .get_strings = sky2_get_strings, |
4267 | .get_coalesce = sky2_get_coalesce, | 4219 | .get_coalesce = sky2_get_coalesce, |
4268 | .set_coalesce = sky2_set_coalesce, | 4220 | .set_coalesce = sky2_set_coalesce, |
@@ -4273,8 +4225,6 @@ static const struct ethtool_ops sky2_ethtool_ops = { | |||
4273 | .set_phys_id = sky2_set_phys_id, | 4225 | .set_phys_id = sky2_set_phys_id, |
4274 | .get_sset_count = sky2_get_sset_count, | 4226 | .get_sset_count = sky2_get_sset_count, |
4275 | .get_ethtool_stats = sky2_get_ethtool_stats, | 4227 | .get_ethtool_stats = sky2_get_ethtool_stats, |
4276 | .set_flags = sky2_set_flags, | ||
4277 | .get_flags = ethtool_op_get_flags, | ||
4278 | }; | 4228 | }; |
4279 | 4229 | ||
4280 | #ifdef CONFIG_SKY2_DEBUG | 4230 | #ifdef CONFIG_SKY2_DEBUG |
@@ -4554,6 +4504,8 @@ static const struct net_device_ops sky2_netdev_ops[2] = { | |||
4554 | .ndo_set_mac_address = sky2_set_mac_address, | 4504 | .ndo_set_mac_address = sky2_set_mac_address, |
4555 | .ndo_set_multicast_list = sky2_set_multicast, | 4505 | .ndo_set_multicast_list = sky2_set_multicast, |
4556 | .ndo_change_mtu = sky2_change_mtu, | 4506 | .ndo_change_mtu = sky2_change_mtu, |
4507 | .ndo_fix_features = sky2_fix_features, | ||
4508 | .ndo_set_features = sky2_set_features, | ||
4557 | .ndo_tx_timeout = sky2_tx_timeout, | 4509 | .ndo_tx_timeout = sky2_tx_timeout, |
4558 | .ndo_get_stats64 = sky2_get_stats, | 4510 | .ndo_get_stats64 = sky2_get_stats, |
4559 | #ifdef CONFIG_NET_POLL_CONTROLLER | 4511 | #ifdef CONFIG_NET_POLL_CONTROLLER |
@@ -4569,6 +4521,8 @@ static const struct net_device_ops sky2_netdev_ops[2] = { | |||
4569 | .ndo_set_mac_address = sky2_set_mac_address, | 4521 | .ndo_set_mac_address = sky2_set_mac_address, |
4570 | .ndo_set_multicast_list = sky2_set_multicast, | 4522 | .ndo_set_multicast_list = sky2_set_multicast, |
4571 | .ndo_change_mtu = sky2_change_mtu, | 4523 | .ndo_change_mtu = sky2_change_mtu, |
4524 | .ndo_fix_features = sky2_fix_features, | ||
4525 | .ndo_set_features = sky2_set_features, | ||
4572 | .ndo_tx_timeout = sky2_tx_timeout, | 4526 | .ndo_tx_timeout = sky2_tx_timeout, |
4573 | .ndo_get_stats64 = sky2_get_stats, | 4527 | .ndo_get_stats64 = sky2_get_stats, |
4574 | }, | 4528 | }, |
@@ -4601,7 +4555,7 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, | |||
4601 | /* Auto speed and flow control */ | 4555 | /* Auto speed and flow control */ |
4602 | sky2->flags = SKY2_FLAG_AUTO_SPEED | SKY2_FLAG_AUTO_PAUSE; | 4556 | sky2->flags = SKY2_FLAG_AUTO_SPEED | SKY2_FLAG_AUTO_PAUSE; |
4603 | if (hw->chip_id != CHIP_ID_YUKON_XL) | 4557 | if (hw->chip_id != CHIP_ID_YUKON_XL) |
4604 | sky2->flags |= SKY2_FLAG_RX_CHECKSUM; | 4558 | dev->hw_features |= NETIF_F_RXCSUM; |
4605 | 4559 | ||
4606 | sky2->flow_mode = FC_BOTH; | 4560 | sky2->flow_mode = FC_BOTH; |
4607 | 4561 | ||
@@ -4620,18 +4574,21 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, | |||
4620 | 4574 | ||
4621 | sky2->port = port; | 4575 | sky2->port = port; |
4622 | 4576 | ||
4623 | dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG | 4577 | dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO; |
4624 | | NETIF_F_TSO | NETIF_F_GRO; | ||
4625 | 4578 | ||
4626 | if (highmem) | 4579 | if (highmem) |
4627 | dev->features |= NETIF_F_HIGHDMA; | 4580 | dev->features |= NETIF_F_HIGHDMA; |
4628 | 4581 | ||
4629 | /* Enable receive hashing unless hardware is known broken */ | 4582 | /* Enable receive hashing unless hardware is known broken */ |
4630 | if (!(hw->flags & SKY2_HW_RSS_BROKEN)) | 4583 | if (!(hw->flags & SKY2_HW_RSS_BROKEN)) |
4631 | dev->features |= NETIF_F_RXHASH; | 4584 | dev->hw_features |= NETIF_F_RXHASH; |
4585 | |||
4586 | if (!(hw->flags & SKY2_HW_VLAN_BROKEN)) { | ||
4587 | dev->hw_features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; | ||
4588 | dev->vlan_features |= SKY2_VLAN_OFFLOADS; | ||
4589 | } | ||
4632 | 4590 | ||
4633 | if (!(hw->flags & SKY2_HW_VLAN_BROKEN)) | 4591 | dev->features |= dev->hw_features; |
4634 | dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; | ||
4635 | 4592 | ||
4636 | /* read the mac address */ | 4593 | /* read the mac address */ |
4637 | memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8, ETH_ALEN); | 4594 | memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8, ETH_ALEN); |
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index 0c6d10c5f053..318c9ae7bf91 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h | |||
@@ -2254,7 +2254,6 @@ struct sky2_port { | |||
2254 | u8 wol; /* WAKE_ bits */ | 2254 | u8 wol; /* WAKE_ bits */ |
2255 | u8 duplex; /* DUPLEX_HALF, DUPLEX_FULL */ | 2255 | u8 duplex; /* DUPLEX_HALF, DUPLEX_FULL */ |
2256 | u16 flags; | 2256 | u16 flags; |
2257 | #define SKY2_FLAG_RX_CHECKSUM 0x0001 | ||
2258 | #define SKY2_FLAG_AUTO_SPEED 0x0002 | 2257 | #define SKY2_FLAG_AUTO_SPEED 0x0002 |
2259 | #define SKY2_FLAG_AUTO_PAUSE 0x0004 | 2258 | #define SKY2_FLAG_AUTO_PAUSE 0x0004 |
2260 | 2259 | ||