aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRajesh Borundia <rajesh.borundia@qlogic.com>2010-08-19 01:08:26 -0400
committerDavid S. Miller <davem@davemloft.net>2010-08-19 19:52:39 -0400
commit0325d69b2a1feb72f11413dbfcc1705ccfc203c1 (patch)
tree55b3d39f86ac2db38bae43209d0ce6111b3abd39
parent4e8acb011f0e9e86e29b53ff051e699ba0c5726d (diff)
qlcnic: configure offload setting on eswitch
Device is not capable of enabling/disabling offload setting per port in case of Nic Partition.So offload settings needs to be enabled/disabled per eswitch and it will affect all the function on that eswitch. Signed-off-by: Rajesh Borundia <rajesh.borundia@qlogic.com> Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/qlcnic/qlcnic_ethtool.c18
-rw-r--r--drivers/net/qlcnic/qlcnic_main.c121
2 files changed, 133 insertions, 6 deletions
diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c
index e38fc3d96d43..2805f88aaf7c 100644
--- a/drivers/net/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/qlcnic/qlcnic_ethtool.c
@@ -804,6 +804,20 @@ qlcnic_get_ethtool_stats(struct net_device *dev,
804 } 804 }
805} 805}
806 806
807static int qlcnic_set_tx_csum(struct net_device *dev, u32 data)
808{
809 struct qlcnic_adapter *adapter = netdev_priv(dev);
810
811 if ((adapter->flags & QLCNIC_ESWITCH_ENABLED))
812 return -EOPNOTSUPP;
813 if (data)
814 dev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
815 else
816 dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
817
818 return 0;
819
820}
807static u32 qlcnic_get_tx_csum(struct net_device *dev) 821static u32 qlcnic_get_tx_csum(struct net_device *dev)
808{ 822{
809 return dev->features & NETIF_F_IP_CSUM; 823 return dev->features & NETIF_F_IP_CSUM;
@@ -819,6 +833,8 @@ static int qlcnic_set_rx_csum(struct net_device *dev, u32 data)
819{ 833{
820 struct qlcnic_adapter *adapter = netdev_priv(dev); 834 struct qlcnic_adapter *adapter = netdev_priv(dev);
821 835
836 if ((adapter->flags & QLCNIC_ESWITCH_ENABLED))
837 return -EOPNOTSUPP;
822 if (!!data) { 838 if (!!data) {
823 adapter->rx_csum = !!data; 839 adapter->rx_csum = !!data;
824 return 0; 840 return 0;
@@ -1070,7 +1086,7 @@ const struct ethtool_ops qlcnic_ethtool_ops = {
1070 .get_pauseparam = qlcnic_get_pauseparam, 1086 .get_pauseparam = qlcnic_get_pauseparam,
1071 .set_pauseparam = qlcnic_set_pauseparam, 1087 .set_pauseparam = qlcnic_set_pauseparam,
1072 .get_tx_csum = qlcnic_get_tx_csum, 1088 .get_tx_csum = qlcnic_get_tx_csum,
1073 .set_tx_csum = ethtool_op_set_tx_csum, 1089 .set_tx_csum = qlcnic_set_tx_csum,
1074 .set_sg = ethtool_op_set_sg, 1090 .set_sg = ethtool_op_set_sg,
1075 .get_tso = qlcnic_get_tso, 1091 .get_tso = qlcnic_get_tso,
1076 .set_tso = qlcnic_set_tso, 1092 .set_tso = qlcnic_set_tso,
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index 7bb32859b928..aa1f6b3c3b80 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -110,6 +110,8 @@ static void qlcnic_dev_set_npar_ready(struct qlcnic_adapter *);
110static int qlcnicvf_config_led(struct qlcnic_adapter *, u32, u32); 110static int qlcnicvf_config_led(struct qlcnic_adapter *, u32, u32);
111static int qlcnicvf_config_bridged_mode(struct qlcnic_adapter *, u32); 111static int qlcnicvf_config_bridged_mode(struct qlcnic_adapter *, u32);
112static int qlcnicvf_start_firmware(struct qlcnic_adapter *); 112static int qlcnicvf_start_firmware(struct qlcnic_adapter *);
113static void qlcnic_set_netdev_features(struct qlcnic_adapter *,
114 struct qlcnic_esw_func_cfg *);
113/* PCI Device ID Table */ 115/* PCI Device ID Table */
114#define ENTRY(device) \ 116#define ENTRY(device) \
115 {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, (device)), \ 117 {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, (device)), \
@@ -756,6 +758,98 @@ qlcnic_check_options(struct qlcnic_adapter *adapter)
756 adapter->max_rds_rings = MAX_RDS_RINGS; 758 adapter->max_rds_rings = MAX_RDS_RINGS;
757} 759}
758 760
761static void
762qlcnic_set_eswitch_port_features(struct qlcnic_adapter *adapter,
763 struct qlcnic_esw_func_cfg *esw_cfg)
764{
765 qlcnic_set_netdev_features(adapter, esw_cfg);
766}
767
768static int
769qlcnic_set_eswitch_port_config(struct qlcnic_adapter *adapter)
770{
771 struct qlcnic_esw_func_cfg esw_cfg;
772
773 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
774 return 0;
775
776 esw_cfg.pci_func = adapter->ahw.pci_func;
777 if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg))
778 return -EIO;
779 qlcnic_set_eswitch_port_features(adapter, &esw_cfg);
780
781 return 0;
782}
783
784static void
785qlcnic_set_netdev_features(struct qlcnic_adapter *adapter,
786 struct qlcnic_esw_func_cfg *esw_cfg)
787{
788 struct net_device *netdev = adapter->netdev;
789 unsigned long features, vlan_features;
790
791 features = (NETIF_F_SG | NETIF_F_IP_CSUM |
792 NETIF_F_IPV6_CSUM | NETIF_F_GRO);
793 vlan_features = (NETIF_F_SG | NETIF_F_IP_CSUM |
794 NETIF_F_IPV6_CSUM);
795
796 if (adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO) {
797 features |= (NETIF_F_TSO | NETIF_F_TSO6);
798 vlan_features |= (NETIF_F_TSO | NETIF_F_TSO6);
799 }
800 if (adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO)
801 features |= NETIF_F_LRO;
802
803 if (esw_cfg->offload_flags & BIT_0) {
804 netdev->features |= features;
805 adapter->rx_csum = 1;
806 if (!(esw_cfg->offload_flags & BIT_1))
807 netdev->features &= ~NETIF_F_TSO;
808 if (!(esw_cfg->offload_flags & BIT_2))
809 netdev->features &= ~NETIF_F_TSO6;
810 } else {
811 netdev->features &= ~features;
812 adapter->rx_csum = 0;
813 }
814
815 netdev->vlan_features = (features & vlan_features);
816}
817
818static int
819qlcnic_set_default_offload_settings(struct qlcnic_adapter *adapter)
820{
821 struct qlcnic_esw_func_cfg esw_cfg;
822 struct qlcnic_npar_info *npar;
823 u8 i;
824
825 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) ||
826 adapter->need_fw_reset ||
827 adapter->op_mode != QLCNIC_MGMT_FUNC)
828 return 0;
829
830 for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
831 if (adapter->npars[i].type != QLCNIC_TYPE_NIC)
832 continue;
833 memset(&esw_cfg, 0, sizeof(struct qlcnic_esw_func_cfg));
834 esw_cfg.pci_func = i;
835 esw_cfg.offload_flags = BIT_0;
836 esw_cfg.mac_learning = BIT_0;
837 if (adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO)
838 esw_cfg.offload_flags |= (BIT_1 | BIT_2);
839 if (qlcnic_config_switch_port(adapter, &esw_cfg))
840 return -EIO;
841 npar = &adapter->npars[i];
842 npar->pvid = esw_cfg.vlan_id;
843 npar->mac_learning = esw_cfg.offload_flags;
844 npar->mac_anti_spoof = esw_cfg.mac_anti_spoof;
845 npar->discard_tagged = esw_cfg.discard_tagged;
846 npar->promisc_mode = esw_cfg.promisc_mode;
847 npar->offload_flags = esw_cfg.offload_flags;
848 }
849
850 return 0;
851}
852
759static int 853static int
760qlcnic_reset_eswitch_config(struct qlcnic_adapter *adapter, 854qlcnic_reset_eswitch_config(struct qlcnic_adapter *adapter,
761 struct qlcnic_npar_info *npar, int pci_func) 855 struct qlcnic_npar_info *npar, int pci_func)
@@ -879,6 +973,8 @@ wait_init:
879 973
880 QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY); 974 QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY);
881 qlcnic_idc_debug_info(adapter, 1); 975 qlcnic_idc_debug_info(adapter, 1);
976 if (qlcnic_set_default_offload_settings(adapter))
977 goto err_out;
882 if (qlcnic_reset_npar_config(adapter)) 978 if (qlcnic_reset_npar_config(adapter))
883 goto err_out; 979 goto err_out;
884 qlcnic_dev_set_npar_ready(adapter); 980 qlcnic_dev_set_npar_ready(adapter);
@@ -974,6 +1070,8 @@ __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev)
974 1070
975 if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) 1071 if (test_bit(__QLCNIC_DEV_UP, &adapter->state))
976 return 0; 1072 return 0;
1073 if (qlcnic_set_eswitch_port_config(adapter))
1074 return -EIO;
977 1075
978 if (qlcnic_fw_create_ctx(adapter)) 1076 if (qlcnic_fw_create_ctx(adapter))
979 return -EIO; 1077 return -EIO;
@@ -1291,7 +1389,6 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter,
1291 1389
1292 if (adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO) 1390 if (adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO)
1293 netdev->features |= NETIF_F_LRO; 1391 netdev->features |= NETIF_F_LRO;
1294
1295 netdev->irq = adapter->msix_entries[0].vector; 1392 netdev->irq = adapter->msix_entries[0].vector;
1296 1393
1297 if (qlcnic_read_mac_addr(adapter)) 1394 if (qlcnic_read_mac_addr(adapter))
@@ -3216,7 +3313,7 @@ qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj,
3216 struct qlcnic_esw_func_cfg *esw_cfg; 3313 struct qlcnic_esw_func_cfg *esw_cfg;
3217 struct qlcnic_npar_info *npar; 3314 struct qlcnic_npar_info *npar;
3218 int count, rem, i, ret; 3315 int count, rem, i, ret;
3219 u8 pci_func; 3316 u8 pci_func, op_mode = 0;
3220 3317
3221 count = size / sizeof(struct qlcnic_esw_func_cfg); 3318 count = size / sizeof(struct qlcnic_esw_func_cfg);
3222 rem = size % sizeof(struct qlcnic_esw_func_cfg); 3319 rem = size % sizeof(struct qlcnic_esw_func_cfg);
@@ -3229,10 +3326,24 @@ qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj,
3229 return ret; 3326 return ret;
3230 3327
3231 for (i = 0; i < count; i++) { 3328 for (i = 0; i < count; i++) {
3232 if (qlcnic_config_switch_port(adapter, &esw_cfg[i])) 3329 if (adapter->op_mode == QLCNIC_MGMT_FUNC)
3233 return QL_STATUS_INVALID_PARAM; 3330 if (qlcnic_config_switch_port(adapter, &esw_cfg[i]))
3331 return QL_STATUS_INVALID_PARAM;
3332 if (adapter->ahw.pci_func == esw_cfg[i].pci_func)
3333 op_mode = esw_cfg[i].op_mode;
3334 qlcnic_get_eswitch_port_config(adapter, &esw_cfg[i]);
3335 esw_cfg[i].op_mode = op_mode;
3336 esw_cfg[i].pci_func = adapter->ahw.pci_func;
3337 switch (esw_cfg[i].op_mode) {
3338 case QLCNIC_PORT_DEFAULTS:
3339 qlcnic_set_eswitch_port_features(adapter,
3340 &esw_cfg[i]);
3341 break;
3342 }
3234 } 3343 }
3235 3344
3345 if (adapter->op_mode != QLCNIC_MGMT_FUNC)
3346 goto out;
3236 for (i = 0; i < count; i++) { 3347 for (i = 0; i < count; i++) {
3237 pci_func = esw_cfg[i].pci_func; 3348 pci_func = esw_cfg[i].pci_func;
3238 npar = &adapter->npars[pci_func]; 3349 npar = &adapter->npars[pci_func];
@@ -3252,7 +3363,7 @@ qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj,
3252 break; 3363 break;
3253 } 3364 }
3254 } 3365 }
3255 3366out:
3256 return size; 3367 return size;
3257} 3368}
3258 3369