aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/qlcnic/qlcnic_main.c
diff options
context:
space:
mode:
authorRajesh Borundia <rajesh.borundia@qlogic.com>2010-08-19 01:08:25 -0400
committerDavid S. Miller <davem@davemloft.net>2010-08-19 19:52:38 -0400
commit4e8acb011f0e9e86e29b53ff051e699ba0c5726d (patch)
treea8f74029aa29ce99403f283a6c33368bda0762b9 /drivers/net/qlcnic/qlcnic_main.c
parent251b036a22f530aff26cf70f5cdb0cf64a072e46 (diff)
qlcnic: configure port on eswitch
o Nic partition capable devices has embedded switch, this needs to support various features like external switch. 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>
Diffstat (limited to 'drivers/net/qlcnic/qlcnic_main.c')
-rw-r--r--drivers/net/qlcnic/qlcnic_main.c185
1 files changed, 102 insertions, 83 deletions
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index c6f19c961c3..7bb32859b92 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -506,7 +506,6 @@ qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
506 adapter->npars[pfn].active = pci_info[i].active; 506 adapter->npars[pfn].active = pci_info[i].active;
507 adapter->npars[pfn].type = pci_info[i].type; 507 adapter->npars[pfn].type = pci_info[i].type;
508 adapter->npars[pfn].phy_port = pci_info[i].default_port; 508 adapter->npars[pfn].phy_port = pci_info[i].default_port;
509 adapter->npars[pfn].mac_learning = DEFAULT_MAC_LEARN;
510 adapter->npars[pfn].min_bw = pci_info[i].tx_min_bw; 509 adapter->npars[pfn].min_bw = pci_info[i].tx_min_bw;
511 adapter->npars[pfn].max_bw = pci_info[i].tx_max_bw; 510 adapter->npars[pfn].max_bw = pci_info[i].tx_max_bw;
512 } 511 }
@@ -758,47 +757,64 @@ qlcnic_check_options(struct qlcnic_adapter *adapter)
758} 757}
759 758
760static int 759static int
760qlcnic_reset_eswitch_config(struct qlcnic_adapter *adapter,
761 struct qlcnic_npar_info *npar, int pci_func)
762{
763 struct qlcnic_esw_func_cfg esw_cfg;
764 esw_cfg.op_mode = QLCNIC_PORT_DEFAULTS;
765 esw_cfg.pci_func = pci_func;
766 esw_cfg.vlan_id = npar->pvid;
767 esw_cfg.mac_learning = npar->mac_learning;
768 esw_cfg.discard_tagged = npar->discard_tagged;
769 esw_cfg.mac_anti_spoof = npar->mac_anti_spoof;
770 esw_cfg.offload_flags = npar->offload_flags;
771 esw_cfg.promisc_mode = npar->promisc_mode;
772 if (qlcnic_config_switch_port(adapter, &esw_cfg))
773 return -EIO;
774
775 esw_cfg.op_mode = QLCNIC_ADD_VLAN;
776 if (qlcnic_config_switch_port(adapter, &esw_cfg))
777 return -EIO;
778
779 return 0;
780}
781
782static int
761qlcnic_reset_npar_config(struct qlcnic_adapter *adapter) 783qlcnic_reset_npar_config(struct qlcnic_adapter *adapter)
762{ 784{
763 int i, err = 0; 785 int i, err;
764 struct qlcnic_npar_info *npar; 786 struct qlcnic_npar_info *npar;
765 struct qlcnic_info nic_info; 787 struct qlcnic_info nic_info;
766 788
767 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) || 789 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) ||
768 !adapter->need_fw_reset) 790 !adapter->need_fw_reset || adapter->op_mode != QLCNIC_MGMT_FUNC)
769 return 0; 791 return 0;
770 792
771 if (adapter->op_mode == QLCNIC_MGMT_FUNC) { 793 /* Set the NPAR config data after FW reset */
772 /* Set the NPAR config data after FW reset */ 794 for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
773 for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { 795 npar = &adapter->npars[i];
774 npar = &adapter->npars[i]; 796 if (npar->type != QLCNIC_TYPE_NIC)
775 if (npar->type != QLCNIC_TYPE_NIC) 797 continue;
776 continue; 798 err = qlcnic_get_nic_info(adapter, &nic_info, i);
777 err = qlcnic_get_nic_info(adapter, &nic_info, i); 799 if (err)
778 if (err) 800 return err;
779 goto err_out; 801 nic_info.min_tx_bw = npar->min_bw;
780 nic_info.min_tx_bw = npar->min_bw; 802 nic_info.max_tx_bw = npar->max_bw;
781 nic_info.max_tx_bw = npar->max_bw; 803 err = qlcnic_set_nic_info(adapter, &nic_info);
782 err = qlcnic_set_nic_info(adapter, &nic_info); 804 if (err)
783 if (err) 805 return err;
784 goto err_out;
785
786 if (npar->enable_pm) {
787 err = qlcnic_config_port_mirroring(adapter,
788 npar->dest_npar, 1, i);
789 if (err)
790 goto err_out;
791 806
792 } 807 if (npar->enable_pm) {
793 npar->mac_learning = DEFAULT_MAC_LEARN; 808 err = qlcnic_config_port_mirroring(adapter,
794 npar->host_vlan_tag = 0; 809 npar->dest_npar, 1, i);
795 npar->promisc_mode = 0; 810 if (err)
796 npar->discard_tagged = 0; 811 return err;
797 npar->vlan_id = 0;
798 } 812 }
813 err = qlcnic_reset_eswitch_config(adapter, npar, i);
814 if (err)
815 return err;
799 } 816 }
800err_out: 817 return 0;
801 return err;
802} 818}
803 819
804static int 820static int
@@ -863,12 +879,10 @@ wait_init:
863 879
864 QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY); 880 QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY);
865 qlcnic_idc_debug_info(adapter, 1); 881 qlcnic_idc_debug_info(adapter, 1);
866
867 qlcnic_check_options(adapter);
868 if (qlcnic_reset_npar_config(adapter)) 882 if (qlcnic_reset_npar_config(adapter))
869 goto err_out; 883 goto err_out;
870 qlcnic_dev_set_npar_ready(adapter); 884 qlcnic_dev_set_npar_ready(adapter);
871 885 qlcnic_check_options(adapter);
872 adapter->need_fw_reset = 0; 886 adapter->need_fw_reset = 0;
873 887
874 qlcnic_release_firmware(adapter); 888 qlcnic_release_firmware(adapter);
@@ -3082,9 +3096,6 @@ validate_pm_config(struct qlcnic_adapter *adapter,
3082 if (adapter->npars[dest_pci_func].type != QLCNIC_TYPE_NIC) 3096 if (adapter->npars[dest_pci_func].type != QLCNIC_TYPE_NIC)
3083 return QL_STATUS_INVALID_PARAM; 3097 return QL_STATUS_INVALID_PARAM;
3084 3098
3085 if (!IS_VALID_MODE(pm_cfg[i].action))
3086 return QL_STATUS_INVALID_PARAM;
3087
3088 s_esw_id = adapter->npars[src_pci_func].phy_port; 3099 s_esw_id = adapter->npars[src_pci_func].phy_port;
3089 d_esw_id = adapter->npars[dest_pci_func].phy_port; 3100 d_esw_id = adapter->npars[dest_pci_func].phy_port;
3090 3101
@@ -3118,7 +3129,7 @@ qlcnic_sysfs_write_pm_config(struct file *filp, struct kobject *kobj,
3118 return ret; 3129 return ret;
3119 for (i = 0; i < count; i++) { 3130 for (i = 0; i < count; i++) {
3120 pci_func = pm_cfg[i].pci_func; 3131 pci_func = pm_cfg[i].pci_func;
3121 action = pm_cfg[i].action; 3132 action = !!pm_cfg[i].action;
3122 id = adapter->npars[pci_func].phy_port; 3133 id = adapter->npars[pci_func].phy_port;
3123 ret = qlcnic_config_port_mirroring(adapter, id, 3134 ret = qlcnic_config_port_mirroring(adapter, id,
3124 action, pci_func); 3135 action, pci_func);
@@ -3129,7 +3140,7 @@ qlcnic_sysfs_write_pm_config(struct file *filp, struct kobject *kobj,
3129 for (i = 0; i < count; i++) { 3140 for (i = 0; i < count; i++) {
3130 pci_func = pm_cfg[i].pci_func; 3141 pci_func = pm_cfg[i].pci_func;
3131 id = adapter->npars[pci_func].phy_port; 3142 id = adapter->npars[pci_func].phy_port;
3132 adapter->npars[pci_func].enable_pm = pm_cfg[i].action; 3143 adapter->npars[pci_func].enable_pm = !!pm_cfg[i].action;
3133 adapter->npars[pci_func].dest_npar = id; 3144 adapter->npars[pci_func].dest_npar = id;
3134 } 3145 }
3135 return size; 3146 return size;
@@ -3161,30 +3172,38 @@ qlcnic_sysfs_read_pm_config(struct file *filp, struct kobject *kobj,
3161 3172
3162static int 3173static int
3163validate_esw_config(struct qlcnic_adapter *adapter, 3174validate_esw_config(struct qlcnic_adapter *adapter,
3164 struct qlcnic_esw_func_cfg *esw_cfg, int count) 3175 struct qlcnic_esw_func_cfg *esw_cfg, int count)
3165{ 3176{
3166 u8 pci_func; 3177 u8 pci_func;
3167 int i; 3178 int i;
3168
3169 for (i = 0; i < count; i++) { 3179 for (i = 0; i < count; i++) {
3170 pci_func = esw_cfg[i].pci_func; 3180 pci_func = esw_cfg[i].pci_func;
3171 if (pci_func >= QLCNIC_MAX_PCI_FUNC) 3181 if (pci_func >= QLCNIC_MAX_PCI_FUNC)
3172 return QL_STATUS_INVALID_PARAM; 3182 return QL_STATUS_INVALID_PARAM;
3173 3183
3174 if (adapter->npars[i].type != QLCNIC_TYPE_NIC) 3184 if (adapter->op_mode == QLCNIC_MGMT_FUNC)
3175 return QL_STATUS_INVALID_PARAM; 3185 if (adapter->npars[pci_func].type != QLCNIC_TYPE_NIC)
3186 return QL_STATUS_INVALID_PARAM;
3176 3187
3177 if (esw_cfg->host_vlan_tag == 1) 3188 switch (esw_cfg[i].op_mode) {
3189 case QLCNIC_PORT_DEFAULTS:
3190 break;
3191 case QLCNIC_ADD_VLAN:
3178 if (!IS_VALID_VLAN(esw_cfg[i].vlan_id)) 3192 if (!IS_VALID_VLAN(esw_cfg[i].vlan_id))
3179 return QL_STATUS_INVALID_PARAM; 3193 return QL_STATUS_INVALID_PARAM;
3180 3194 if (!esw_cfg[i].op_type)
3181 if (!IS_VALID_MODE(esw_cfg[i].promisc_mode) 3195 return QL_STATUS_INVALID_PARAM;
3182 || !IS_VALID_MODE(esw_cfg[i].host_vlan_tag) 3196 break;
3183 || !IS_VALID_MODE(esw_cfg[i].mac_learning) 3197 case QLCNIC_DEL_VLAN:
3184 || !IS_VALID_MODE(esw_cfg[i].discard_tagged)) 3198 if (!IS_VALID_VLAN(esw_cfg[i].vlan_id))
3199 return QL_STATUS_INVALID_PARAM;
3200 if (!esw_cfg[i].op_type)
3201 return QL_STATUS_INVALID_PARAM;
3202 break;
3203 default:
3185 return QL_STATUS_INVALID_PARAM; 3204 return QL_STATUS_INVALID_PARAM;
3205 }
3186 } 3206 }
3187
3188 return 0; 3207 return 0;
3189} 3208}
3190 3209
@@ -3195,8 +3214,9 @@ qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj,
3195 struct device *dev = container_of(kobj, struct device, kobj); 3214 struct device *dev = container_of(kobj, struct device, kobj);
3196 struct qlcnic_adapter *adapter = dev_get_drvdata(dev); 3215 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
3197 struct qlcnic_esw_func_cfg *esw_cfg; 3216 struct qlcnic_esw_func_cfg *esw_cfg;
3217 struct qlcnic_npar_info *npar;
3198 int count, rem, i, ret; 3218 int count, rem, i, ret;
3199 u8 id, pci_func; 3219 u8 pci_func;
3200 3220
3201 count = size / sizeof(struct qlcnic_esw_func_cfg); 3221 count = size / sizeof(struct qlcnic_esw_func_cfg);
3202 rem = size % sizeof(struct qlcnic_esw_func_cfg); 3222 rem = size % sizeof(struct qlcnic_esw_func_cfg);
@@ -3209,28 +3229,28 @@ qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj,
3209 return ret; 3229 return ret;
3210 3230
3211 for (i = 0; i < count; i++) { 3231 for (i = 0; i < count; i++) {
3212 pci_func = esw_cfg[i].pci_func; 3232 if (qlcnic_config_switch_port(adapter, &esw_cfg[i]))
3213 id = adapter->npars[pci_func].phy_port; 3233 return QL_STATUS_INVALID_PARAM;
3214 ret = qlcnic_config_switch_port(adapter, id,
3215 esw_cfg[i].host_vlan_tag,
3216 esw_cfg[i].discard_tagged,
3217 esw_cfg[i].promisc_mode,
3218 esw_cfg[i].mac_learning,
3219 esw_cfg[i].pci_func,
3220 esw_cfg[i].vlan_id);
3221 if (ret)
3222 return ret;
3223 } 3234 }
3224 3235
3225 for (i = 0; i < count; i++) { 3236 for (i = 0; i < count; i++) {
3226 pci_func = esw_cfg[i].pci_func; 3237 pci_func = esw_cfg[i].pci_func;
3227 adapter->npars[pci_func].promisc_mode = esw_cfg[i].promisc_mode; 3238 npar = &adapter->npars[pci_func];
3228 adapter->npars[pci_func].mac_learning = esw_cfg[i].mac_learning; 3239 switch (esw_cfg[i].op_mode) {
3229 adapter->npars[pci_func].vlan_id = esw_cfg[i].vlan_id; 3240 case QLCNIC_PORT_DEFAULTS:
3230 adapter->npars[pci_func].discard_tagged = 3241 npar->promisc_mode = esw_cfg[i].promisc_mode;
3231 esw_cfg[i].discard_tagged; 3242 npar->mac_learning = esw_cfg[i].mac_learning;
3232 adapter->npars[pci_func].host_vlan_tag = 3243 npar->offload_flags = esw_cfg[i].offload_flags;
3233 esw_cfg[i].host_vlan_tag; 3244 npar->mac_anti_spoof = esw_cfg[i].mac_anti_spoof;
3245 npar->discard_tagged = esw_cfg[i].discard_tagged;
3246 break;
3247 case QLCNIC_ADD_VLAN:
3248 npar->pvid = esw_cfg[i].vlan_id;
3249 break;
3250 case QLCNIC_DEL_VLAN:
3251 npar->pvid = 0;
3252 break;
3253 }
3234 } 3254 }
3235 3255
3236 return size; 3256 return size;
@@ -3243,7 +3263,7 @@ qlcnic_sysfs_read_esw_config(struct file *file, struct kobject *kobj,
3243 struct device *dev = container_of(kobj, struct device, kobj); 3263 struct device *dev = container_of(kobj, struct device, kobj);
3244 struct qlcnic_adapter *adapter = dev_get_drvdata(dev); 3264 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
3245 struct qlcnic_esw_func_cfg esw_cfg[QLCNIC_MAX_PCI_FUNC]; 3265 struct qlcnic_esw_func_cfg esw_cfg[QLCNIC_MAX_PCI_FUNC];
3246 int i; 3266 u8 i;
3247 3267
3248 if (size != sizeof(esw_cfg)) 3268 if (size != sizeof(esw_cfg))
3249 return QL_STATUS_INVALID_PARAM; 3269 return QL_STATUS_INVALID_PARAM;
@@ -3251,12 +3271,9 @@ qlcnic_sysfs_read_esw_config(struct file *file, struct kobject *kobj,
3251 for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { 3271 for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
3252 if (adapter->npars[i].type != QLCNIC_TYPE_NIC) 3272 if (adapter->npars[i].type != QLCNIC_TYPE_NIC)
3253 continue; 3273 continue;
3254 3274 esw_cfg[i].pci_func = i;
3255 esw_cfg[i].host_vlan_tag = adapter->npars[i].host_vlan_tag; 3275 if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg[i]))
3256 esw_cfg[i].promisc_mode = adapter->npars[i].promisc_mode; 3276 return QL_STATUS_INVALID_PARAM;
3257 esw_cfg[i].discard_tagged = adapter->npars[i].discard_tagged;
3258 esw_cfg[i].vlan_id = adapter->npars[i].vlan_id;
3259 esw_cfg[i].mac_learning = adapter->npars[i].mac_learning;
3260 } 3277 }
3261 memcpy(buf, &esw_cfg, size); 3278 memcpy(buf, &esw_cfg, size);
3262 3279
@@ -3580,15 +3597,16 @@ qlcnic_create_diag_entries(struct qlcnic_adapter *adapter)
3580 dev_info(dev, "failed to create crb sysfs entry\n"); 3597 dev_info(dev, "failed to create crb sysfs entry\n");
3581 if (device_create_bin_file(dev, &bin_attr_mem)) 3598 if (device_create_bin_file(dev, &bin_attr_mem))
3582 dev_info(dev, "failed to create mem sysfs entry\n"); 3599 dev_info(dev, "failed to create mem sysfs entry\n");
3583 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) || 3600 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
3584 adapter->op_mode != QLCNIC_MGMT_FUNC) 3601 return;
3602 if (device_create_bin_file(dev, &bin_attr_esw_config))
3603 dev_info(dev, "failed to create esw config sysfs entry");
3604 if (adapter->op_mode != QLCNIC_MGMT_FUNC)
3585 return; 3605 return;
3586 if (device_create_bin_file(dev, &bin_attr_pci_config)) 3606 if (device_create_bin_file(dev, &bin_attr_pci_config))
3587 dev_info(dev, "failed to create pci config sysfs entry"); 3607 dev_info(dev, "failed to create pci config sysfs entry");
3588 if (device_create_bin_file(dev, &bin_attr_npar_config)) 3608 if (device_create_bin_file(dev, &bin_attr_npar_config))
3589 dev_info(dev, "failed to create npar config sysfs entry"); 3609 dev_info(dev, "failed to create npar config sysfs entry");
3590 if (device_create_bin_file(dev, &bin_attr_esw_config))
3591 dev_info(dev, "failed to create esw config sysfs entry");
3592 if (device_create_bin_file(dev, &bin_attr_pm_config)) 3610 if (device_create_bin_file(dev, &bin_attr_pm_config))
3593 dev_info(dev, "failed to create pm config sysfs entry"); 3611 dev_info(dev, "failed to create pm config sysfs entry");
3594 if (device_create_bin_file(dev, &bin_attr_esw_stats)) 3612 if (device_create_bin_file(dev, &bin_attr_esw_stats))
@@ -3607,12 +3625,13 @@ qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter)
3607 device_remove_file(dev, &dev_attr_diag_mode); 3625 device_remove_file(dev, &dev_attr_diag_mode);
3608 device_remove_bin_file(dev, &bin_attr_crb); 3626 device_remove_bin_file(dev, &bin_attr_crb);
3609 device_remove_bin_file(dev, &bin_attr_mem); 3627 device_remove_bin_file(dev, &bin_attr_mem);
3610 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) || 3628 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
3611 adapter->op_mode != QLCNIC_MGMT_FUNC) 3629 return;
3630 device_remove_bin_file(dev, &bin_attr_esw_config);
3631 if (adapter->op_mode != QLCNIC_MGMT_FUNC)
3612 return; 3632 return;
3613 device_remove_bin_file(dev, &bin_attr_pci_config); 3633 device_remove_bin_file(dev, &bin_attr_pci_config);
3614 device_remove_bin_file(dev, &bin_attr_npar_config); 3634 device_remove_bin_file(dev, &bin_attr_npar_config);
3615 device_remove_bin_file(dev, &bin_attr_esw_config);
3616 device_remove_bin_file(dev, &bin_attr_pm_config); 3635 device_remove_bin_file(dev, &bin_attr_pm_config);
3617 device_remove_bin_file(dev, &bin_attr_esw_stats); 3636 device_remove_bin_file(dev, &bin_attr_esw_stats);
3618} 3637}