aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/dm9000.c57
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
473static uint32_t dm9000_get_rx_csum(struct net_device *dev) 471static 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
479static 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
493static 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
506static 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
516static u32 dm9000_get_link(struct net_device *dev) 487static 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
652static void dm9000_show_carrier(board_info_t *db, 619static 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 */