diff options
-rw-r--r-- | drivers/net/dm9000.c | 57 |
1 files changed, 13 insertions, 44 deletions
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index b7af5bab9937..f7bdebbcb908 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c | |||
@@ -131,8 +131,6 @@ typedef struct board_info { | |||
131 | u32 msg_enable; | 131 | u32 msg_enable; |
132 | u32 wake_state; | 132 | u32 wake_state; |
133 | 133 | ||
134 | int rx_csum; | ||
135 | int can_csum; | ||
136 | int ip_summed; | 134 | int ip_summed; |
137 | } board_info_t; | 135 | } board_info_t; |
138 | 136 | ||
@@ -470,47 +468,20 @@ static int dm9000_nway_reset(struct net_device *dev) | |||
470 | return mii_nway_restart(&dm->mii); | 468 | return mii_nway_restart(&dm->mii); |
471 | } | 469 | } |
472 | 470 | ||
473 | static uint32_t dm9000_get_rx_csum(struct net_device *dev) | 471 | static int dm9000_set_features(struct net_device *dev, u32 features) |
474 | { | 472 | { |
475 | board_info_t *dm = to_dm9000_board(dev); | 473 | board_info_t *dm = to_dm9000_board(dev); |
476 | return dm->rx_csum; | 474 | u32 changed = dev->features ^ features; |
477 | } | 475 | unsigned long flags; |
478 | |||
479 | static int dm9000_set_rx_csum_unlocked(struct net_device *dev, uint32_t data) | ||
480 | { | ||
481 | board_info_t *dm = to_dm9000_board(dev); | ||
482 | |||
483 | if (dm->can_csum) { | ||
484 | dm->rx_csum = data; | ||
485 | iow(dm, DM9000_RCSR, dm->rx_csum ? RCSR_CSUM : 0); | ||
486 | 476 | ||
477 | if (!(changed & NETIF_F_RXCSUM)) | ||
487 | return 0; | 478 | return 0; |
488 | } | ||
489 | |||
490 | return -EOPNOTSUPP; | ||
491 | } | ||
492 | |||
493 | static int dm9000_set_rx_csum(struct net_device *dev, uint32_t data) | ||
494 | { | ||
495 | board_info_t *dm = to_dm9000_board(dev); | ||
496 | unsigned long flags; | ||
497 | int ret; | ||
498 | 479 | ||
499 | spin_lock_irqsave(&dm->lock, flags); | 480 | spin_lock_irqsave(&dm->lock, flags); |
500 | ret = dm9000_set_rx_csum_unlocked(dev, data); | 481 | iow(dm, DM9000_RCSR, (features & NETIF_F_RXCSUM) ? RCSR_CSUM : 0); |
501 | spin_unlock_irqrestore(&dm->lock, flags); | 482 | spin_unlock_irqrestore(&dm->lock, flags); |
502 | 483 | ||
503 | return ret; | 484 | return 0; |
504 | } | ||
505 | |||
506 | static int dm9000_set_tx_csum(struct net_device *dev, uint32_t data) | ||
507 | { | ||
508 | board_info_t *dm = to_dm9000_board(dev); | ||
509 | int ret = -EOPNOTSUPP; | ||
510 | |||
511 | if (dm->can_csum) | ||
512 | ret = ethtool_op_set_tx_csum(dev, data); | ||
513 | return ret; | ||
514 | } | 485 | } |
515 | 486 | ||
516 | static u32 dm9000_get_link(struct net_device *dev) | 487 | static u32 dm9000_get_link(struct net_device *dev) |
@@ -643,10 +614,6 @@ static const struct ethtool_ops dm9000_ethtool_ops = { | |||
643 | .get_eeprom_len = dm9000_get_eeprom_len, | 614 | .get_eeprom_len = dm9000_get_eeprom_len, |
644 | .get_eeprom = dm9000_get_eeprom, | 615 | .get_eeprom = dm9000_get_eeprom, |
645 | .set_eeprom = dm9000_set_eeprom, | 616 | .set_eeprom = dm9000_set_eeprom, |
646 | .get_rx_csum = dm9000_get_rx_csum, | ||
647 | .set_rx_csum = dm9000_set_rx_csum, | ||
648 | .get_tx_csum = ethtool_op_get_tx_csum, | ||
649 | .set_tx_csum = dm9000_set_tx_csum, | ||
650 | }; | 617 | }; |
651 | 618 | ||
652 | static void dm9000_show_carrier(board_info_t *db, | 619 | static void dm9000_show_carrier(board_info_t *db, |
@@ -800,7 +767,9 @@ dm9000_init_dm9000(struct net_device *dev) | |||
800 | db->io_mode = ior(db, DM9000_ISR) >> 6; /* ISR bit7:6 keeps I/O mode */ | 767 | db->io_mode = ior(db, DM9000_ISR) >> 6; /* ISR bit7:6 keeps I/O mode */ |
801 | 768 | ||
802 | /* Checksum mode */ | 769 | /* Checksum mode */ |
803 | dm9000_set_rx_csum_unlocked(dev, db->rx_csum); | 770 | if (dev->hw_features & NETIF_F_RXCSUM) |
771 | iow(dm, DM9000_RCSR, | ||
772 | (dev->features & NETIF_F_RXCSUM) ? RCSR_CSUM : 0); | ||
804 | 773 | ||
805 | iow(db, DM9000_GPCR, GPCR_GEP_CNTL); /* Let GPIO0 output */ | 774 | iow(db, DM9000_GPCR, GPCR_GEP_CNTL); /* Let GPIO0 output */ |
806 | 775 | ||
@@ -1049,7 +1018,7 @@ dm9000_rx(struct net_device *dev) | |||
1049 | 1018 | ||
1050 | /* Pass to upper layer */ | 1019 | /* Pass to upper layer */ |
1051 | skb->protocol = eth_type_trans(skb, dev); | 1020 | skb->protocol = eth_type_trans(skb, dev); |
1052 | if (db->rx_csum) { | 1021 | if (dev->features & NETIF_F_RXCSUM) { |
1053 | if ((((rxbyte & 0x1c) << 3) & rxbyte) == 0) | 1022 | if ((((rxbyte & 0x1c) << 3) & rxbyte) == 0) |
1054 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 1023 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
1055 | else | 1024 | else |
@@ -1358,6 +1327,7 @@ static const struct net_device_ops dm9000_netdev_ops = { | |||
1358 | .ndo_set_multicast_list = dm9000_hash_table, | 1327 | .ndo_set_multicast_list = dm9000_hash_table, |
1359 | .ndo_do_ioctl = dm9000_ioctl, | 1328 | .ndo_do_ioctl = dm9000_ioctl, |
1360 | .ndo_change_mtu = eth_change_mtu, | 1329 | .ndo_change_mtu = eth_change_mtu, |
1330 | .ndo_set_features = dm9000_set_features, | ||
1361 | .ndo_validate_addr = eth_validate_addr, | 1331 | .ndo_validate_addr = eth_validate_addr, |
1362 | .ndo_set_mac_address = eth_mac_addr, | 1332 | .ndo_set_mac_address = eth_mac_addr, |
1363 | #ifdef CONFIG_NET_POLL_CONTROLLER | 1333 | #ifdef CONFIG_NET_POLL_CONTROLLER |
@@ -1551,9 +1521,8 @@ dm9000_probe(struct platform_device *pdev) | |||
1551 | 1521 | ||
1552 | /* dm9000a/b are capable of hardware checksum offload */ | 1522 | /* dm9000a/b are capable of hardware checksum offload */ |
1553 | if (db->type == TYPE_DM9000A || db->type == TYPE_DM9000B) { | 1523 | if (db->type == TYPE_DM9000A || db->type == TYPE_DM9000B) { |
1554 | db->can_csum = 1; | 1524 | ndev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM; |
1555 | db->rx_csum = 1; | 1525 | ndev->features |= ndev->hw_features; |
1556 | ndev->features |= NETIF_F_IP_CSUM; | ||
1557 | } | 1526 | } |
1558 | 1527 | ||
1559 | /* from this point we assume that we have found a DM9000 */ | 1528 | /* from this point we assume that we have found a DM9000 */ |