aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/qlogic
diff options
context:
space:
mode:
authorShahed Shaikh <shahed.shaikh@qlogic.com>2013-05-21 05:27:01 -0400
committerDavid S. Miller <davem@davemloft.net>2013-05-22 17:52:40 -0400
commit147a90887baa98d73db1fa7ed9e755bf48960c21 (patch)
treea86f12f683de6ca93113ded2498b89748dd0f8b5 /drivers/net/ethernet/qlogic
parent0ce54ce4aaef1389fb8d640271748ace257cb763 (diff)
qlcnic: Fix updating netdev->features
o After change in EPORT features of 82xx adapter, netdev->features needs to be updated to reflect EPORT feature updates but driver was manipulating netdev->features at wrong place. o This patch uses netdev_update_features() and .ndo_fix_features() to update netdev->features properly. Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/qlogic')
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic.h6
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c49
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c49
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c3
4 files changed, 61 insertions, 46 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index 019c5f78732e..c1b693cb3df3 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -907,8 +907,11 @@ struct qlcnic_ipaddr {
907#define QLCNIC_FW_HANG 0x4000 907#define QLCNIC_FW_HANG 0x4000
908#define QLCNIC_FW_LRO_MSS_CAP 0x8000 908#define QLCNIC_FW_LRO_MSS_CAP 0x8000
909#define QLCNIC_TX_INTR_SHARED 0x10000 909#define QLCNIC_TX_INTR_SHARED 0x10000
910#define QLCNIC_APP_CHANGED_FLAGS 0x20000
910#define QLCNIC_IS_MSI_FAMILY(adapter) \ 911#define QLCNIC_IS_MSI_FAMILY(adapter) \
911 ((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED)) 912 ((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED))
913#define QLCNIC_IS_TSO_CAPABLE(adapter) \
914 ((adapter)->ahw->capabilities & QLCNIC_FW_CAPABILITY_TSO)
912 915
913#define QLCNIC_DEF_NUM_STS_DESC_RINGS 4 916#define QLCNIC_DEF_NUM_STS_DESC_RINGS 4
914#define QLCNIC_MSIX_TBL_SPACE 8192 917#define QLCNIC_MSIX_TBL_SPACE 8192
@@ -1034,6 +1037,7 @@ struct qlcnic_adapter {
1034 spinlock_t rx_mac_learn_lock; 1037 spinlock_t rx_mac_learn_lock;
1035 u32 file_prd_off; /*File fw product offset*/ 1038 u32 file_prd_off; /*File fw product offset*/
1036 u32 fw_version; 1039 u32 fw_version;
1040 u32 offload_flags;
1037 const struct firmware *fw; 1041 const struct firmware *fw;
1038}; 1042};
1039 1043
@@ -1542,6 +1546,8 @@ void qlcnic_add_lb_filter(struct qlcnic_adapter *, struct sk_buff *, int, u16);
1542int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter); 1546int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter);
1543int qlcnic_read_mac_addr(struct qlcnic_adapter *); 1547int qlcnic_read_mac_addr(struct qlcnic_adapter *);
1544int qlcnic_setup_netdev(struct qlcnic_adapter *, struct net_device *, int); 1548int qlcnic_setup_netdev(struct qlcnic_adapter *, struct net_device *, int);
1549void qlcnic_set_netdev_features(struct qlcnic_adapter *,
1550 struct qlcnic_esw_func_cfg *);
1545void qlcnic_sriov_vf_schedule_multi(struct net_device *); 1551void qlcnic_sriov_vf_schedule_multi(struct net_device *);
1546void qlcnic_vf_add_mc_list(struct net_device *, u16); 1552void qlcnic_vf_add_mc_list(struct net_device *, u16);
1547 1553
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
index 6a6512ba9f38..106a12f2a02f 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
@@ -973,16 +973,57 @@ int qlcnic_change_mtu(struct net_device *netdev, int mtu)
973 return rc; 973 return rc;
974} 974}
975 975
976static netdev_features_t qlcnic_process_flags(struct qlcnic_adapter *adapter,
977 netdev_features_t features)
978{
979 u32 offload_flags = adapter->offload_flags;
980
981 if (offload_flags & BIT_0) {
982 features |= NETIF_F_RXCSUM | NETIF_F_IP_CSUM |
983 NETIF_F_IPV6_CSUM;
984 adapter->rx_csum = 1;
985 if (QLCNIC_IS_TSO_CAPABLE(adapter)) {
986 if (!(offload_flags & BIT_1))
987 features &= ~NETIF_F_TSO;
988 else
989 features |= NETIF_F_TSO;
990
991 if (!(offload_flags & BIT_2))
992 features &= ~NETIF_F_TSO6;
993 else
994 features |= NETIF_F_TSO6;
995 }
996 } else {
997 features &= ~(NETIF_F_RXCSUM |
998 NETIF_F_IP_CSUM |
999 NETIF_F_IPV6_CSUM);
1000
1001 if (QLCNIC_IS_TSO_CAPABLE(adapter))
1002 features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
1003 adapter->rx_csum = 0;
1004 }
1005
1006 return features;
1007}
976 1008
977netdev_features_t qlcnic_fix_features(struct net_device *netdev, 1009netdev_features_t qlcnic_fix_features(struct net_device *netdev,
978 netdev_features_t features) 1010 netdev_features_t features)
979{ 1011{
980 struct qlcnic_adapter *adapter = netdev_priv(netdev); 1012 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1013 netdev_features_t changed;
981 1014
982 if ((adapter->flags & QLCNIC_ESWITCH_ENABLED) && 1015 if (qlcnic_82xx_check(adapter) &&
983 qlcnic_82xx_check(adapter)) { 1016 (adapter->flags & QLCNIC_ESWITCH_ENABLED)) {
984 netdev_features_t changed = features ^ netdev->features; 1017 if (adapter->flags & QLCNIC_APP_CHANGED_FLAGS) {
985 features ^= changed & (NETIF_F_ALL_CSUM | NETIF_F_RXCSUM); 1018 features = qlcnic_process_flags(adapter, features);
1019 } else {
1020 changed = features ^ netdev->features;
1021 features ^= changed & (NETIF_F_RXCSUM |
1022 NETIF_F_IP_CSUM |
1023 NETIF_F_IPV6_CSUM |
1024 NETIF_F_TSO |
1025 NETIF_F_TSO6);
1026 }
986 } 1027 }
987 1028
988 if (!(features & NETIF_F_RXCSUM)) 1029 if (!(features & NETIF_F_RXCSUM))
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 0da38df51793..aeb26a850679 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -84,14 +84,9 @@ static int qlcnic_start_firmware(struct qlcnic_adapter *);
84static void qlcnic_free_lb_filters_mem(struct qlcnic_adapter *adapter); 84static void qlcnic_free_lb_filters_mem(struct qlcnic_adapter *adapter);
85static void qlcnic_dev_set_npar_ready(struct qlcnic_adapter *); 85static void qlcnic_dev_set_npar_ready(struct qlcnic_adapter *);
86static int qlcnicvf_start_firmware(struct qlcnic_adapter *); 86static int qlcnicvf_start_firmware(struct qlcnic_adapter *);
87static void qlcnic_set_netdev_features(struct qlcnic_adapter *,
88 struct qlcnic_esw_func_cfg *);
89static int qlcnic_vlan_rx_add(struct net_device *, __be16, u16); 87static int qlcnic_vlan_rx_add(struct net_device *, __be16, u16);
90static int qlcnic_vlan_rx_del(struct net_device *, __be16, u16); 88static int qlcnic_vlan_rx_del(struct net_device *, __be16, u16);
91 89
92#define QLCNIC_IS_TSO_CAPABLE(adapter) \
93 ((adapter)->ahw->capabilities & QLCNIC_FW_CAPABILITY_TSO)
94
95static u32 qlcnic_vlan_tx_check(struct qlcnic_adapter *adapter) 90static u32 qlcnic_vlan_tx_check(struct qlcnic_adapter *adapter)
96{ 91{
97 struct qlcnic_hardware_context *ahw = adapter->ahw; 92 struct qlcnic_hardware_context *ahw = adapter->ahw;
@@ -1074,8 +1069,6 @@ void qlcnic_set_eswitch_port_features(struct qlcnic_adapter *adapter,
1074 1069
1075 if (!esw_cfg->promisc_mode) 1070 if (!esw_cfg->promisc_mode)
1076 adapter->flags |= QLCNIC_PROMISC_DISABLED; 1071 adapter->flags |= QLCNIC_PROMISC_DISABLED;
1077
1078 qlcnic_set_netdev_features(adapter, esw_cfg);
1079} 1072}
1080 1073
1081int qlcnic_set_eswitch_port_config(struct qlcnic_adapter *adapter) 1074int qlcnic_set_eswitch_port_config(struct qlcnic_adapter *adapter)
@@ -1090,51 +1083,23 @@ int qlcnic_set_eswitch_port_config(struct qlcnic_adapter *adapter)
1090 return -EIO; 1083 return -EIO;
1091 qlcnic_set_vlan_config(adapter, &esw_cfg); 1084 qlcnic_set_vlan_config(adapter, &esw_cfg);
1092 qlcnic_set_eswitch_port_features(adapter, &esw_cfg); 1085 qlcnic_set_eswitch_port_features(adapter, &esw_cfg);
1086 qlcnic_set_netdev_features(adapter, &esw_cfg);
1093 1087
1094 return 0; 1088 return 0;
1095} 1089}
1096 1090
1097static void 1091void qlcnic_set_netdev_features(struct qlcnic_adapter *adapter,
1098qlcnic_set_netdev_features(struct qlcnic_adapter *adapter, 1092 struct qlcnic_esw_func_cfg *esw_cfg)
1099 struct qlcnic_esw_func_cfg *esw_cfg)
1100{ 1093{
1101 struct net_device *netdev = adapter->netdev; 1094 struct net_device *netdev = adapter->netdev;
1102 unsigned long features, vlan_features;
1103 1095
1104 if (qlcnic_83xx_check(adapter)) 1096 if (qlcnic_83xx_check(adapter))
1105 return; 1097 return;
1106 1098
1107 features = (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM | 1099 adapter->offload_flags = esw_cfg->offload_flags;
1108 NETIF_F_IPV6_CSUM | NETIF_F_GRO); 1100 adapter->flags |= QLCNIC_APP_CHANGED_FLAGS;
1109 vlan_features = (NETIF_F_SG | NETIF_F_IP_CSUM | 1101 netdev_update_features(netdev);
1110 NETIF_F_IPV6_CSUM); 1102 adapter->flags &= ~QLCNIC_APP_CHANGED_FLAGS;
1111
1112 if (QLCNIC_IS_TSO_CAPABLE(adapter)) {
1113 features |= (NETIF_F_TSO | NETIF_F_TSO6);
1114 vlan_features |= (NETIF_F_TSO | NETIF_F_TSO6);
1115 }
1116
1117 if (netdev->features & NETIF_F_LRO)
1118 features |= NETIF_F_LRO;
1119
1120 if (esw_cfg->offload_flags & BIT_0) {
1121 netdev->features |= features;
1122 adapter->rx_csum = 1;
1123 if (!(esw_cfg->offload_flags & BIT_1)) {
1124 netdev->features &= ~NETIF_F_TSO;
1125 features &= ~NETIF_F_TSO;
1126 }
1127 if (!(esw_cfg->offload_flags & BIT_2)) {
1128 netdev->features &= ~NETIF_F_TSO6;
1129 features &= ~NETIF_F_TSO6;
1130 }
1131 } else {
1132 netdev->features &= ~features;
1133 features &= ~features;
1134 adapter->rx_csum = 0;
1135 }
1136
1137 netdev->vlan_features = (features & vlan_features);
1138} 1103}
1139 1104
1140static int 1105static int
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c
index 4e22e794a186..e7a2fe21b649 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c
@@ -544,6 +544,9 @@ static ssize_t qlcnic_sysfs_write_esw_config(struct file *file,
544 switch (esw_cfg[i].op_mode) { 544 switch (esw_cfg[i].op_mode) {
545 case QLCNIC_PORT_DEFAULTS: 545 case QLCNIC_PORT_DEFAULTS:
546 qlcnic_set_eswitch_port_features(adapter, &esw_cfg[i]); 546 qlcnic_set_eswitch_port_features(adapter, &esw_cfg[i]);
547 rtnl_lock();
548 qlcnic_set_netdev_features(adapter, &esw_cfg[i]);
549 rtnl_unlock();
547 break; 550 break;
548 case QLCNIC_ADD_VLAN: 551 case QLCNIC_ADD_VLAN:
549 qlcnic_set_vlan_config(adapter, &esw_cfg[i]); 552 qlcnic_set_vlan_config(adapter, &esw_cfg[i]);