aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichał Mirosław <mirq-linux@rere.qmqm.pl>2011-04-18 23:03:57 -0400
committerDavid S. Miller <davem@davemloft.net>2011-04-20 04:30:44 -0400
commit135d84a9f28854f875f32f97485737b0013c99d6 (patch)
tree5e42b4b9321c7a69908090efde029517cc868191
parentb9367bf3ee6da380e0c338bd75bb8e8e4e0b981b (diff)
net: qlcnic: convert to hw_features
Bit more than minimal conversion. There might be some issues because of qlcnic_set_netdev_features() if it's called after netdev init. 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/qlcnic/qlcnic.h3
-rw-r--r--drivers/net/qlcnic/qlcnic_ethtool.c120
-rw-r--r--drivers/net/qlcnic/qlcnic_hw.c37
-rw-r--r--drivers/net/qlcnic/qlcnic_init.c4
-rw-r--r--drivers/net/qlcnic/qlcnic_main.c35
5 files changed, 57 insertions, 142 deletions
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index e5d30538f37..fa5b15c474b 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -926,7 +926,6 @@ struct qlcnic_adapter {
926 u8 max_rds_rings; 926 u8 max_rds_rings;
927 u8 max_sds_rings; 927 u8 max_sds_rings;
928 u8 msix_supported; 928 u8 msix_supported;
929 u8 rx_csum;
930 u8 portnum; 929 u8 portnum;
931 u8 physical_port; 930 u8 physical_port;
932 u8 reset_context; 931 u8 reset_context;
@@ -1247,6 +1246,8 @@ void qlcnic_advert_link_change(struct qlcnic_adapter *adapter, int linkup);
1247 1246
1248int qlcnic_fw_cmd_set_mtu(struct qlcnic_adapter *adapter, int mtu); 1247int qlcnic_fw_cmd_set_mtu(struct qlcnic_adapter *adapter, int mtu);
1249int qlcnic_change_mtu(struct net_device *netdev, int new_mtu); 1248int qlcnic_change_mtu(struct net_device *netdev, int new_mtu);
1249u32 qlcnic_fix_features(struct net_device *netdev, u32 features);
1250int qlcnic_set_features(struct net_device *netdev, u32 features);
1250int qlcnic_config_hw_lro(struct qlcnic_adapter *adapter, int enable); 1251int qlcnic_config_hw_lro(struct qlcnic_adapter *adapter, int enable);
1251int qlcnic_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable); 1252int qlcnic_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable);
1252int qlcnic_send_lro_cleanup(struct qlcnic_adapter *adapter); 1253int qlcnic_send_lro_cleanup(struct qlcnic_adapter *adapter);
diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c
index 3cd8a169694..615a5ab8845 100644
--- a/drivers/net/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/qlcnic/qlcnic_ethtool.c
@@ -764,73 +764,6 @@ qlcnic_get_ethtool_stats(struct net_device *dev,
764 qlcnic_fill_device_stats(&index, data, &port_stats.tx); 764 qlcnic_fill_device_stats(&index, data, &port_stats.tx);
765} 765}
766 766
767static int qlcnic_set_tx_csum(struct net_device *dev, u32 data)
768{
769 struct qlcnic_adapter *adapter = netdev_priv(dev);
770
771 if ((adapter->flags & QLCNIC_ESWITCH_ENABLED))
772 return -EOPNOTSUPP;
773 if (data)
774 dev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
775 else
776 dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
777
778 return 0;
779
780}
781static u32 qlcnic_get_tx_csum(struct net_device *dev)
782{
783 return dev->features & NETIF_F_IP_CSUM;
784}
785
786static u32 qlcnic_get_rx_csum(struct net_device *dev)
787{
788 struct qlcnic_adapter *adapter = netdev_priv(dev);
789 return adapter->rx_csum;
790}
791
792static int qlcnic_set_rx_csum(struct net_device *dev, u32 data)
793{
794 struct qlcnic_adapter *adapter = netdev_priv(dev);
795
796 if ((adapter->flags & QLCNIC_ESWITCH_ENABLED))
797 return -EOPNOTSUPP;
798 if (!!data) {
799 adapter->rx_csum = !!data;
800 return 0;
801 }
802
803 if (dev->features & NETIF_F_LRO) {
804 if (qlcnic_config_hw_lro(adapter, QLCNIC_LRO_DISABLED))
805 return -EIO;
806
807 dev->features &= ~NETIF_F_LRO;
808 qlcnic_send_lro_cleanup(adapter);
809 dev_info(&adapter->pdev->dev,
810 "disabling LRO as rx_csum is off\n");
811 }
812 adapter->rx_csum = !!data;
813 return 0;
814}
815
816static u32 qlcnic_get_tso(struct net_device *dev)
817{
818 return (dev->features & (NETIF_F_TSO | NETIF_F_TSO6)) != 0;
819}
820
821static int qlcnic_set_tso(struct net_device *dev, u32 data)
822{
823 struct qlcnic_adapter *adapter = netdev_priv(dev);
824 if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO))
825 return -EOPNOTSUPP;
826 if (data)
827 dev->features |= (NETIF_F_TSO | NETIF_F_TSO6);
828 else
829 dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
830
831 return 0;
832}
833
834static int qlcnic_set_led(struct net_device *dev, 767static int qlcnic_set_led(struct net_device *dev,
835 enum ethtool_phys_id_state state) 768 enum ethtool_phys_id_state state)
836{ 769{
@@ -993,50 +926,6 @@ static int qlcnic_get_intr_coalesce(struct net_device *netdev,
993 return 0; 926 return 0;
994} 927}
995 928
996static int qlcnic_set_flags(struct net_device *netdev, u32 data)
997{
998 struct qlcnic_adapter *adapter = netdev_priv(netdev);
999 int hw_lro;
1000
1001 if (ethtool_invalid_flags(netdev, data, ETH_FLAG_LRO))
1002 return -EINVAL;
1003
1004 if (data & ETH_FLAG_LRO) {
1005
1006 if (netdev->features & NETIF_F_LRO)
1007 return 0;
1008
1009 if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO))
1010 return -EINVAL;
1011
1012 if (!adapter->rx_csum) {
1013 dev_info(&adapter->pdev->dev, "rx csum is off, "
1014 "cannot toggle lro\n");
1015 return -EINVAL;
1016 }
1017
1018 hw_lro = QLCNIC_LRO_ENABLED;
1019 netdev->features |= NETIF_F_LRO;
1020
1021 } else {
1022
1023 if (!(netdev->features & NETIF_F_LRO))
1024 return 0;
1025
1026 hw_lro = 0;
1027 netdev->features &= ~NETIF_F_LRO;
1028 }
1029
1030 if (qlcnic_config_hw_lro(adapter, hw_lro))
1031 return -EIO;
1032
1033 if ((hw_lro == 0) && qlcnic_send_lro_cleanup(adapter))
1034 return -EIO;
1035
1036
1037 return 0;
1038}
1039
1040static u32 qlcnic_get_msglevel(struct net_device *netdev) 929static u32 qlcnic_get_msglevel(struct net_device *netdev)
1041{ 930{
1042 struct qlcnic_adapter *adapter = netdev_priv(netdev); 931 struct qlcnic_adapter *adapter = netdev_priv(netdev);
@@ -1064,23 +953,14 @@ const struct ethtool_ops qlcnic_ethtool_ops = {
1064 .set_ringparam = qlcnic_set_ringparam, 953 .set_ringparam = qlcnic_set_ringparam,
1065 .get_pauseparam = qlcnic_get_pauseparam, 954 .get_pauseparam = qlcnic_get_pauseparam,
1066 .set_pauseparam = qlcnic_set_pauseparam, 955 .set_pauseparam = qlcnic_set_pauseparam,
1067 .get_tx_csum = qlcnic_get_tx_csum,
1068 .set_tx_csum = qlcnic_set_tx_csum,
1069 .set_sg = ethtool_op_set_sg,
1070 .get_tso = qlcnic_get_tso,
1071 .set_tso = qlcnic_set_tso,
1072 .get_wol = qlcnic_get_wol, 956 .get_wol = qlcnic_get_wol,
1073 .set_wol = qlcnic_set_wol, 957 .set_wol = qlcnic_set_wol,
1074 .self_test = qlcnic_diag_test, 958 .self_test = qlcnic_diag_test,
1075 .get_strings = qlcnic_get_strings, 959 .get_strings = qlcnic_get_strings,
1076 .get_ethtool_stats = qlcnic_get_ethtool_stats, 960 .get_ethtool_stats = qlcnic_get_ethtool_stats,
1077 .get_sset_count = qlcnic_get_sset_count, 961 .get_sset_count = qlcnic_get_sset_count,
1078 .get_rx_csum = qlcnic_get_rx_csum,
1079 .set_rx_csum = qlcnic_set_rx_csum,
1080 .get_coalesce = qlcnic_get_intr_coalesce, 962 .get_coalesce = qlcnic_get_intr_coalesce,
1081 .set_coalesce = qlcnic_set_intr_coalesce, 963 .set_coalesce = qlcnic_set_intr_coalesce,
1082 .get_flags = ethtool_op_get_flags,
1083 .set_flags = qlcnic_set_flags,
1084 .set_phys_id = qlcnic_set_led, 964 .set_phys_id = qlcnic_set_led,
1085 .set_msglevel = qlcnic_set_msglevel, 965 .set_msglevel = qlcnic_set_msglevel,
1086 .get_msglevel = qlcnic_get_msglevel, 966 .get_msglevel = qlcnic_get_msglevel,
diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c
index 498cca92126..cbb27f2df00 100644
--- a/drivers/net/qlcnic/qlcnic_hw.c
+++ b/drivers/net/qlcnic/qlcnic_hw.c
@@ -758,6 +758,43 @@ int qlcnic_change_mtu(struct net_device *netdev, int mtu)
758 return rc; 758 return rc;
759} 759}
760 760
761
762u32 qlcnic_fix_features(struct net_device *netdev, u32 features)
763{
764 struct qlcnic_adapter *adapter = netdev_priv(netdev);
765
766 if ((adapter->flags & QLCNIC_ESWITCH_ENABLED)) {
767 u32 changed = features ^ netdev->features;
768 features ^= changed & (NETIF_F_ALL_CSUM | NETIF_F_RXCSUM);
769 }
770
771 if (!(features & NETIF_F_RXCSUM))
772 features &= ~NETIF_F_LRO;
773
774 return features;
775}
776
777
778int qlcnic_set_features(struct net_device *netdev, u32 features)
779{
780 struct qlcnic_adapter *adapter = netdev_priv(netdev);
781 u32 changed = netdev->features ^ features;
782 int hw_lro = (features & NETIF_F_LRO) ? QLCNIC_LRO_ENABLED : 0;
783
784 if (!(changed & NETIF_F_LRO))
785 return 0;
786
787 netdev->features = features ^ NETIF_F_LRO;
788
789 if (qlcnic_config_hw_lro(adapter, hw_lro))
790 return -EIO;
791
792 if ((hw_lro == 0) && qlcnic_send_lro_cleanup(adapter))
793 return -EIO;
794
795 return 0;
796}
797
761/* 798/*
762 * Changes the CRB window to the specified window. 799 * Changes the CRB window to the specified window.
763 */ 800 */
diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c
index 4ec0eeb6bff..d0f338b0139 100644
--- a/drivers/net/qlcnic/qlcnic_init.c
+++ b/drivers/net/qlcnic/qlcnic_init.c
@@ -1390,8 +1390,8 @@ static struct sk_buff *qlcnic_process_rxbuf(struct qlcnic_adapter *adapter,
1390 1390
1391 skb = buffer->skb; 1391 skb = buffer->skb;
1392 1392
1393 if (likely(adapter->rx_csum && (cksum == STATUS_CKSUM_OK || 1393 if (likely((adapter->netdev->features & NETIF_F_RXCSUM) &&
1394 cksum == STATUS_CKSUM_LOOP))) { 1394 (cksum == STATUS_CKSUM_OK || cksum == STATUS_CKSUM_LOOP))) {
1395 adapter->stats.csummed++; 1395 adapter->stats.csummed++;
1396 skb->ip_summed = CHECKSUM_UNNECESSARY; 1396 skb->ip_summed = CHECKSUM_UNNECESSARY;
1397 } else { 1397 } else {
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index e9e9ba6efc5..6e619514fee 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -328,6 +328,8 @@ static const struct net_device_ops qlcnic_netdev_ops = {
328 .ndo_set_multicast_list = qlcnic_set_multi, 328 .ndo_set_multicast_list = qlcnic_set_multi,
329 .ndo_set_mac_address = qlcnic_set_mac, 329 .ndo_set_mac_address = qlcnic_set_mac,
330 .ndo_change_mtu = qlcnic_change_mtu, 330 .ndo_change_mtu = qlcnic_change_mtu,
331 .ndo_fix_features = qlcnic_fix_features,
332 .ndo_set_features = qlcnic_set_features,
331 .ndo_tx_timeout = qlcnic_tx_timeout, 333 .ndo_tx_timeout = qlcnic_tx_timeout,
332 .ndo_vlan_rx_add_vid = qlcnic_vlan_rx_add, 334 .ndo_vlan_rx_add_vid = qlcnic_vlan_rx_add,
333 .ndo_vlan_rx_kill_vid = qlcnic_vlan_rx_del, 335 .ndo_vlan_rx_kill_vid = qlcnic_vlan_rx_del,
@@ -764,7 +766,7 @@ qlcnic_set_netdev_features(struct qlcnic_adapter *adapter,
764 struct net_device *netdev = adapter->netdev; 766 struct net_device *netdev = adapter->netdev;
765 unsigned long features, vlan_features; 767 unsigned long features, vlan_features;
766 768
767 features = (NETIF_F_SG | NETIF_F_IP_CSUM | 769 features = (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
768 NETIF_F_IPV6_CSUM | NETIF_F_GRO); 770 NETIF_F_IPV6_CSUM | NETIF_F_GRO);
769 vlan_features = (NETIF_F_SG | NETIF_F_IP_CSUM | 771 vlan_features = (NETIF_F_SG | NETIF_F_IP_CSUM |
770 NETIF_F_IPV6_CSUM | NETIF_F_HW_VLAN_FILTER); 772 NETIF_F_IPV6_CSUM | NETIF_F_HW_VLAN_FILTER);
@@ -779,14 +781,12 @@ qlcnic_set_netdev_features(struct qlcnic_adapter *adapter,
779 781
780 if (esw_cfg->offload_flags & BIT_0) { 782 if (esw_cfg->offload_flags & BIT_0) {
781 netdev->features |= features; 783 netdev->features |= features;
782 adapter->rx_csum = 1;
783 if (!(esw_cfg->offload_flags & BIT_1)) 784 if (!(esw_cfg->offload_flags & BIT_1))
784 netdev->features &= ~NETIF_F_TSO; 785 netdev->features &= ~NETIF_F_TSO;
785 if (!(esw_cfg->offload_flags & BIT_2)) 786 if (!(esw_cfg->offload_flags & BIT_2))
786 netdev->features &= ~NETIF_F_TSO6; 787 netdev->features &= ~NETIF_F_TSO6;
787 } else { 788 } else {
788 netdev->features &= ~features; 789 netdev->features &= ~features;
789 adapter->rx_csum = 0;
790 } 790 }
791 791
792 netdev->vlan_features = (features & vlan_features); 792 netdev->vlan_features = (features & vlan_features);
@@ -1436,7 +1436,6 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter,
1436 int err; 1436 int err;
1437 struct pci_dev *pdev = adapter->pdev; 1437 struct pci_dev *pdev = adapter->pdev;
1438 1438
1439 adapter->rx_csum = 1;
1440 adapter->mc_enabled = 0; 1439 adapter->mc_enabled = 0;
1441 adapter->max_mc_count = 38; 1440 adapter->max_mc_count = 38;
1442 1441
@@ -1447,26 +1446,24 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter,
1447 1446
1448 SET_ETHTOOL_OPS(netdev, &qlcnic_ethtool_ops); 1447 SET_ETHTOOL_OPS(netdev, &qlcnic_ethtool_ops);
1449 1448
1450 netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | 1449 netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM |
1451 NETIF_F_IPV6_CSUM | NETIF_F_GRO | NETIF_F_HW_VLAN_RX); 1450 NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM;
1452 netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM |
1453 NETIF_F_IPV6_CSUM | NETIF_F_HW_VLAN_FILTER);
1454 1451
1455 if (adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO) { 1452 if (adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO)
1456 netdev->features |= (NETIF_F_TSO | NETIF_F_TSO6); 1453 netdev->hw_features |= NETIF_F_TSO | NETIF_F_TSO6;
1457 netdev->vlan_features |= (NETIF_F_TSO | NETIF_F_TSO6); 1454 if (pci_using_dac)
1458 } 1455 netdev->hw_features |= NETIF_F_HIGHDMA;
1459 1456
1460 if (pci_using_dac) { 1457 netdev->vlan_features = netdev->hw_features;
1461 netdev->features |= NETIF_F_HIGHDMA;
1462 netdev->vlan_features |= NETIF_F_HIGHDMA;
1463 }
1464 1458
1465 if (adapter->capabilities & QLCNIC_FW_CAPABILITY_FVLANTX) 1459 if (adapter->capabilities & QLCNIC_FW_CAPABILITY_FVLANTX)
1466 netdev->features |= (NETIF_F_HW_VLAN_TX); 1460 netdev->hw_features |= NETIF_F_HW_VLAN_TX;
1467
1468 if (adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO) 1461 if (adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO)
1469 netdev->features |= NETIF_F_LRO; 1462 netdev->hw_features |= NETIF_F_LRO;
1463
1464 netdev->features |= netdev->hw_features |
1465 NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER;
1466
1470 netdev->irq = adapter->msix_entries[0].vector; 1467 netdev->irq = adapter->msix_entries[0].vector;
1471 1468
1472 netif_carrier_off(netdev); 1469 netif_carrier_off(netdev);