aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/fcoe
diff options
context:
space:
mode:
authorRobert Love <robert.w.love@intel.com>2012-05-22 22:06:26 -0400
committerJames Bottomley <JBottomley@Parallels.com>2012-05-23 04:43:13 -0400
commit8d55e507d24c6db7eb012c379c62912e642eb75e (patch)
tree5118b221cf9eab4ad040c9e1bcabb794e57dc906 /drivers/scsi/fcoe
parent9a74e884ee71dbf3d0967b0321d7b4529a04826c (diff)
[SCSI] fcoe, bnx2fc, libfcoe: SW FCoE and bnx2fc use FCoE Syfs
This patch has the SW FCoE driver and the bnx2fc driver make use of the new fcoe_sysfs API added earlier in this patch series. After this patch a fcoe_ctlr_device is allocated with private data in this order. +------------------+ +------------------+ | fcoe_ctlr_device | | fcoe_ctlr_device | +------------------+ +------------------+ | fcoe_ctlr | | fcoe_ctlr | +------------------+ +------------------+ | fcoe_interface | | bnx2fc_interface | +------------------+ +------------------+ libfcoe also takes part in this new model since it discovers and manages fcoe_fcf instances. The memory allocation is different for FCFs. I didn't want to impact libfcoe's fcoe_fcf processing, so this patch creates fcoe_fcf_device instances for each discovered fcoe_fcf. The two are paired using a (void * priv) member of the fcoe_ctlr_device. This allows libfcoe to continue maintaining its list of fcoe_fcf instances and simply attaches and detaches them from existing or new fcoe_fcf_device instances. Signed-off-by: Robert Love <robert.w.love@intel.com> Tested-by: Ross Brattain <ross.b.brattain@intel.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/fcoe')
-rw-r--r--drivers/scsi/fcoe/fcoe.c71
-rw-r--r--drivers/scsi/fcoe/fcoe_ctlr.c159
2 files changed, 209 insertions, 21 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index 4bb42e19d537..fe30b1b65e1d 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -41,6 +41,7 @@
41 41
42#include <scsi/fc/fc_encaps.h> 42#include <scsi/fc/fc_encaps.h>
43#include <scsi/fc/fc_fip.h> 43#include <scsi/fc/fc_fip.h>
44#include <scsi/fc/fc_fcoe.h>
44 45
45#include <scsi/libfc.h> 46#include <scsi/libfc.h>
46#include <scsi/fc_frame.h> 47#include <scsi/fc_frame.h>
@@ -150,6 +151,21 @@ static int fcoe_vport_create(struct fc_vport *, bool disabled);
150static int fcoe_vport_disable(struct fc_vport *, bool disable); 151static int fcoe_vport_disable(struct fc_vport *, bool disable);
151static void fcoe_set_vport_symbolic_name(struct fc_vport *); 152static void fcoe_set_vport_symbolic_name(struct fc_vport *);
152static void fcoe_set_port_id(struct fc_lport *, u32, struct fc_frame *); 153static void fcoe_set_port_id(struct fc_lport *, u32, struct fc_frame *);
154static void fcoe_ctlr_get_lesb(struct fcoe_ctlr_device *);
155static void fcoe_fcf_get_vlan_id(struct fcoe_fcf_device *);
156
157static struct fcoe_sysfs_function_template fcoe_sysfs_templ = {
158 .get_fcoe_ctlr_mode = fcoe_ctlr_get_fip_mode,
159 .get_fcoe_ctlr_link_fail = fcoe_ctlr_get_lesb,
160 .get_fcoe_ctlr_vlink_fail = fcoe_ctlr_get_lesb,
161 .get_fcoe_ctlr_miss_fka = fcoe_ctlr_get_lesb,
162 .get_fcoe_ctlr_symb_err = fcoe_ctlr_get_lesb,
163 .get_fcoe_ctlr_err_block = fcoe_ctlr_get_lesb,
164 .get_fcoe_ctlr_fcs_error = fcoe_ctlr_get_lesb,
165
166 .get_fcoe_fcf_selected = fcoe_fcf_get_selected,
167 .get_fcoe_fcf_vlan_id = fcoe_fcf_get_vlan_id,
168};
153 169
154static struct libfc_function_template fcoe_libfc_fcn_templ = { 170static struct libfc_function_template fcoe_libfc_fcn_templ = {
155 .frame_send = fcoe_xmit, 171 .frame_send = fcoe_xmit,
@@ -366,6 +382,7 @@ static int fcoe_interface_setup(struct fcoe_interface *fcoe,
366static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev, 382static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev,
367 enum fip_state fip_mode) 383 enum fip_state fip_mode)
368{ 384{
385 struct fcoe_ctlr_device *ctlr_dev;
369 struct fcoe_ctlr *ctlr; 386 struct fcoe_ctlr *ctlr;
370 struct fcoe_interface *fcoe; 387 struct fcoe_interface *fcoe;
371 int size; 388 int size;
@@ -379,14 +396,17 @@ static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev,
379 } 396 }
380 397
381 size = sizeof(struct fcoe_ctlr) + sizeof(struct fcoe_interface); 398 size = sizeof(struct fcoe_ctlr) + sizeof(struct fcoe_interface);
382 ctlr = kzalloc(size, GFP_KERNEL); 399 ctlr_dev = fcoe_ctlr_device_add(&netdev->dev, &fcoe_sysfs_templ,
383 fcoe = fcoe_ctlr_priv(ctlr); 400 size);
384 if (!fcoe) { 401 if (!ctlr_dev) {
385 FCOE_NETDEV_DBG(netdev, "Could not allocate fcoe structure\n"); 402 FCOE_DBG("Failed to add fcoe_ctlr_device\n");
386 fcoe = ERR_PTR(-ENOMEM); 403 fcoe = ERR_PTR(-ENOMEM);
387 goto out_putmod; 404 goto out_putmod;
388 } 405 }
389 406
407 ctlr = fcoe_ctlr_device_priv(ctlr_dev);
408 fcoe = fcoe_ctlr_priv(ctlr);
409
390 dev_hold(netdev); 410 dev_hold(netdev);
391 411
392 /* 412 /*
@@ -400,6 +420,7 @@ static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev,
400 err = fcoe_interface_setup(fcoe, netdev); 420 err = fcoe_interface_setup(fcoe, netdev);
401 if (err) { 421 if (err) {
402 fcoe_ctlr_destroy(ctlr); 422 fcoe_ctlr_destroy(ctlr);
423 fcoe_ctlr_device_delete(ctlr_dev);
403 dev_put(netdev); 424 dev_put(netdev);
404 fcoe = ERR_PTR(err); 425 fcoe = ERR_PTR(err);
405 goto out_putmod; 426 goto out_putmod;
@@ -466,6 +487,7 @@ static void fcoe_interface_cleanup(struct fcoe_interface *fcoe)
466{ 487{
467 struct net_device *netdev = fcoe->netdev; 488 struct net_device *netdev = fcoe->netdev;
468 struct fcoe_ctlr *fip = fcoe_to_ctlr(fcoe); 489 struct fcoe_ctlr *fip = fcoe_to_ctlr(fcoe);
490 struct fcoe_ctlr_device *ctlr_dev = fcoe_ctlr_to_ctlr_dev(fip);
469 491
470 rtnl_lock(); 492 rtnl_lock();
471 if (!fcoe->removed) 493 if (!fcoe->removed)
@@ -476,7 +498,7 @@ static void fcoe_interface_cleanup(struct fcoe_interface *fcoe)
476 /* tear-down the FCoE controller */ 498 /* tear-down the FCoE controller */
477 fcoe_ctlr_destroy(fip); 499 fcoe_ctlr_destroy(fip);
478 scsi_host_put(fip->lp->host); 500 scsi_host_put(fip->lp->host);
479 kfree(fip); 501 fcoe_ctlr_device_delete(ctlr_dev);
480 dev_put(netdev); 502 dev_put(netdev);
481 module_put(THIS_MODULE); 503 module_put(THIS_MODULE);
482} 504}
@@ -2196,6 +2218,7 @@ static void fcoe_dcb_create(struct fcoe_interface *fcoe)
2196static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode) 2218static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode)
2197{ 2219{
2198 int rc = 0; 2220 int rc = 0;
2221 struct fcoe_ctlr_device *ctlr_dev;
2199 struct fcoe_ctlr *ctlr; 2222 struct fcoe_ctlr *ctlr;
2200 struct fcoe_interface *fcoe; 2223 struct fcoe_interface *fcoe;
2201 struct fc_lport *lport; 2224 struct fc_lport *lport;
@@ -2216,8 +2239,8 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode)
2216 } 2239 }
2217 2240
2218 ctlr = fcoe_to_ctlr(fcoe); 2241 ctlr = fcoe_to_ctlr(fcoe);
2219 2242 ctlr_dev = fcoe_ctlr_to_ctlr_dev(ctlr);
2220 lport = fcoe_if_create(fcoe, &netdev->dev, 0); 2243 lport = fcoe_if_create(fcoe, &ctlr_dev->dev, 0);
2221 if (IS_ERR(lport)) { 2244 if (IS_ERR(lport)) {
2222 printk(KERN_ERR "fcoe: Failed to create interface (%s)\n", 2245 printk(KERN_ERR "fcoe: Failed to create interface (%s)\n",
2223 netdev->name); 2246 netdev->name);
@@ -2768,6 +2791,40 @@ static void fcoe_get_lesb(struct fc_lport *lport,
2768 __fcoe_get_lesb(lport, fc_lesb, netdev); 2791 __fcoe_get_lesb(lport, fc_lesb, netdev);
2769} 2792}
2770 2793
2794static void fcoe_ctlr_get_lesb(struct fcoe_ctlr_device *ctlr_dev)
2795{
2796 struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr_dev);
2797 struct net_device *netdev = fcoe_netdev(fip->lp);
2798 struct fcoe_fc_els_lesb *fcoe_lesb;
2799 struct fc_els_lesb fc_lesb;
2800
2801 __fcoe_get_lesb(fip->lp, &fc_lesb, netdev);
2802 fcoe_lesb = (struct fcoe_fc_els_lesb *)(&fc_lesb);
2803
2804 ctlr_dev->lesb.lesb_link_fail =
2805 ntohl(fcoe_lesb->lesb_link_fail);
2806 ctlr_dev->lesb.lesb_vlink_fail =
2807 ntohl(fcoe_lesb->lesb_vlink_fail);
2808 ctlr_dev->lesb.lesb_miss_fka =
2809 ntohl(fcoe_lesb->lesb_miss_fka);
2810 ctlr_dev->lesb.lesb_symb_err =
2811 ntohl(fcoe_lesb->lesb_symb_err);
2812 ctlr_dev->lesb.lesb_err_block =
2813 ntohl(fcoe_lesb->lesb_err_block);
2814 ctlr_dev->lesb.lesb_fcs_error =
2815 ntohl(fcoe_lesb->lesb_fcs_error);
2816}
2817
2818static void fcoe_fcf_get_vlan_id(struct fcoe_fcf_device *fcf_dev)
2819{
2820 struct fcoe_ctlr_device *ctlr_dev =
2821 fcoe_fcf_dev_to_ctlr_dev(fcf_dev);
2822 struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev);
2823 struct fcoe_interface *fcoe = fcoe_ctlr_priv(ctlr);
2824
2825 fcf_dev->vlan_id = vlan_dev_vlan_id(fcoe->netdev);
2826}
2827
2771/** 2828/**
2772 * fcoe_set_port_id() - Callback from libfc when Port_ID is set. 2829 * fcoe_set_port_id() - Callback from libfc when Port_ID is set.
2773 * @lport: the local port 2830 * @lport: the local port
diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c
index 5a4c7250aa77..d68d57241ee6 100644
--- a/drivers/scsi/fcoe/fcoe_ctlr.c
+++ b/drivers/scsi/fcoe/fcoe_ctlr.c
@@ -160,6 +160,76 @@ void fcoe_ctlr_init(struct fcoe_ctlr *fip, enum fip_state mode)
160} 160}
161EXPORT_SYMBOL(fcoe_ctlr_init); 161EXPORT_SYMBOL(fcoe_ctlr_init);
162 162
163static int fcoe_sysfs_fcf_add(struct fcoe_fcf *new)
164{
165 struct fcoe_ctlr *fip = new->fip;
166 struct fcoe_ctlr_device *ctlr_dev = fcoe_ctlr_to_ctlr_dev(fip);
167 struct fcoe_fcf_device temp, *fcf_dev;
168 int rc = 0;
169
170 LIBFCOE_FIP_DBG(fip, "New FCF fab %16.16llx mac %pM\n",
171 new->fabric_name, new->fcf_mac);
172
173 mutex_lock(&ctlr_dev->lock);
174
175 temp.fabric_name = new->fabric_name;
176 temp.switch_name = new->switch_name;
177 temp.fc_map = new->fc_map;
178 temp.vfid = new->vfid;
179 memcpy(temp.mac, new->fcf_mac, ETH_ALEN);
180 temp.priority = new->pri;
181 temp.fka_period = new->fka_period;
182 temp.selected = 0; /* default to unselected */
183
184 fcf_dev = fcoe_fcf_device_add(ctlr_dev, &temp);
185 if (unlikely(!fcf_dev)) {
186 rc = -ENOMEM;
187 goto out;
188 }
189
190 /*
191 * The fcoe_sysfs layer can return a CONNECTED fcf that
192 * has a priv (fcf was never deleted) or a CONNECTED fcf
193 * that doesn't have a priv (fcf was deleted). However,
194 * libfcoe will always delete FCFs before trying to add
195 * them. This is ensured because both recv_adv and
196 * age_fcfs are protected by the the fcoe_ctlr's mutex.
197 * This means that we should never get a FCF with a
198 * non-NULL priv pointer.
199 */
200 BUG_ON(fcf_dev->priv);
201
202 fcf_dev->priv = new;
203 new->fcf_dev = fcf_dev;
204
205 list_add(&new->list, &fip->fcfs);
206 fip->fcf_count++;
207
208out:
209 mutex_unlock(&ctlr_dev->lock);
210 return rc;
211}
212
213static void fcoe_sysfs_fcf_del(struct fcoe_fcf *new)
214{
215 struct fcoe_ctlr *fip = new->fip;
216 struct fcoe_ctlr_device *ctlr_dev = fcoe_ctlr_to_ctlr_dev(fip);
217 struct fcoe_fcf_device *fcf_dev;
218
219 list_del(&new->list);
220 fip->fcf_count--;
221
222 mutex_lock(&ctlr_dev->lock);
223
224 fcf_dev = fcoe_fcf_to_fcf_dev(new);
225 WARN_ON(!fcf_dev);
226 new->fcf_dev = NULL;
227 fcoe_fcf_device_delete(fcf_dev);
228 kfree(new);
229
230 mutex_unlock(&ctlr_dev->lock);
231}
232
163/** 233/**
164 * fcoe_ctlr_reset_fcfs() - Reset and free all FCFs for a controller 234 * fcoe_ctlr_reset_fcfs() - Reset and free all FCFs for a controller
165 * @fip: The FCoE controller whose FCFs are to be reset 235 * @fip: The FCoE controller whose FCFs are to be reset
@@ -173,10 +243,10 @@ static void fcoe_ctlr_reset_fcfs(struct fcoe_ctlr *fip)
173 243
174 fip->sel_fcf = NULL; 244 fip->sel_fcf = NULL;
175 list_for_each_entry_safe(fcf, next, &fip->fcfs, list) { 245 list_for_each_entry_safe(fcf, next, &fip->fcfs, list) {
176 list_del(&fcf->list); 246 fcoe_sysfs_fcf_del(fcf);
177 kfree(fcf);
178 } 247 }
179 fip->fcf_count = 0; 248 WARN_ON(fip->fcf_count);
249
180 fip->sel_time = 0; 250 fip->sel_time = 0;
181} 251}
182 252
@@ -717,8 +787,11 @@ static unsigned long fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip)
717 unsigned long next_timer = jiffies + msecs_to_jiffies(FIP_VN_KA_PERIOD); 787 unsigned long next_timer = jiffies + msecs_to_jiffies(FIP_VN_KA_PERIOD);
718 unsigned long deadline; 788 unsigned long deadline;
719 unsigned long sel_time = 0; 789 unsigned long sel_time = 0;
790 struct list_head del_list;
720 struct fcoe_dev_stats *stats; 791 struct fcoe_dev_stats *stats;
721 792
793 INIT_LIST_HEAD(&del_list);
794
722 stats = per_cpu_ptr(fip->lp->dev_stats, get_cpu()); 795 stats = per_cpu_ptr(fip->lp->dev_stats, get_cpu());
723 796
724 list_for_each_entry_safe(fcf, next, &fip->fcfs, list) { 797 list_for_each_entry_safe(fcf, next, &fip->fcfs, list) {
@@ -739,10 +812,13 @@ static unsigned long fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip)
739 if (time_after_eq(jiffies, deadline)) { 812 if (time_after_eq(jiffies, deadline)) {
740 if (fip->sel_fcf == fcf) 813 if (fip->sel_fcf == fcf)
741 fip->sel_fcf = NULL; 814 fip->sel_fcf = NULL;
815 /*
816 * Move to delete list so we can call
817 * fcoe_sysfs_fcf_del (which can sleep)
818 * after the put_cpu().
819 */
742 list_del(&fcf->list); 820 list_del(&fcf->list);
743 WARN_ON(!fip->fcf_count); 821 list_add(&fcf->list, &del_list);
744 fip->fcf_count--;
745 kfree(fcf);
746 stats->VLinkFailureCount++; 822 stats->VLinkFailureCount++;
747 } else { 823 } else {
748 if (time_after(next_timer, deadline)) 824 if (time_after(next_timer, deadline))
@@ -753,6 +829,12 @@ static unsigned long fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip)
753 } 829 }
754 } 830 }
755 put_cpu(); 831 put_cpu();
832
833 list_for_each_entry_safe(fcf, next, &del_list, list) {
834 /* Removes fcf from current list */
835 fcoe_sysfs_fcf_del(fcf);
836 }
837
756 if (sel_time && !fip->sel_fcf && !fip->sel_time) { 838 if (sel_time && !fip->sel_fcf && !fip->sel_time) {
757 sel_time += msecs_to_jiffies(FCOE_CTLR_START_DELAY); 839 sel_time += msecs_to_jiffies(FCOE_CTLR_START_DELAY);
758 fip->sel_time = sel_time; 840 fip->sel_time = sel_time;
@@ -903,23 +985,23 @@ static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb)
903{ 985{
904 struct fcoe_fcf *fcf; 986 struct fcoe_fcf *fcf;
905 struct fcoe_fcf new; 987 struct fcoe_fcf new;
906 struct fcoe_fcf *found;
907 unsigned long sol_tov = msecs_to_jiffies(FCOE_CTRL_SOL_TOV); 988 unsigned long sol_tov = msecs_to_jiffies(FCOE_CTRL_SOL_TOV);
908 int first = 0; 989 int first = 0;
909 int mtu_valid; 990 int mtu_valid;
991 int found = 0;
992 int rc = 0;
910 993
911 if (fcoe_ctlr_parse_adv(fip, skb, &new)) 994 if (fcoe_ctlr_parse_adv(fip, skb, &new))
912 return; 995 return;
913 996
914 mutex_lock(&fip->ctlr_mutex); 997 mutex_lock(&fip->ctlr_mutex);
915 first = list_empty(&fip->fcfs); 998 first = list_empty(&fip->fcfs);
916 found = NULL;
917 list_for_each_entry(fcf, &fip->fcfs, list) { 999 list_for_each_entry(fcf, &fip->fcfs, list) {
918 if (fcf->switch_name == new.switch_name && 1000 if (fcf->switch_name == new.switch_name &&
919 fcf->fabric_name == new.fabric_name && 1001 fcf->fabric_name == new.fabric_name &&
920 fcf->fc_map == new.fc_map && 1002 fcf->fc_map == new.fc_map &&
921 compare_ether_addr(fcf->fcf_mac, new.fcf_mac) == 0) { 1003 compare_ether_addr(fcf->fcf_mac, new.fcf_mac) == 0) {
922 found = fcf; 1004 found = 1;
923 break; 1005 break;
924 } 1006 }
925 } 1007 }
@@ -931,9 +1013,16 @@ static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb)
931 if (!fcf) 1013 if (!fcf)
932 goto out; 1014 goto out;
933 1015
934 fip->fcf_count++;
935 memcpy(fcf, &new, sizeof(new)); 1016 memcpy(fcf, &new, sizeof(new));
936 list_add(&fcf->list, &fip->fcfs); 1017 fcf->fip = fip;
1018 rc = fcoe_sysfs_fcf_add(fcf);
1019 if (rc) {
1020 printk(KERN_ERR "Failed to allocate sysfs instance "
1021 "for FCF, fab %16.16llx mac %pM\n",
1022 new.fabric_name, new.fcf_mac);
1023 kfree(fcf);
1024 goto out;
1025 }
937 } else { 1026 } else {
938 /* 1027 /*
939 * Update the FCF's keep-alive descriptor flags. 1028 * Update the FCF's keep-alive descriptor flags.
@@ -954,6 +1043,7 @@ static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb)
954 fcf->fka_period = new.fka_period; 1043 fcf->fka_period = new.fka_period;
955 memcpy(fcf->fcf_mac, new.fcf_mac, ETH_ALEN); 1044 memcpy(fcf->fcf_mac, new.fcf_mac, ETH_ALEN);
956 } 1045 }
1046
957 mtu_valid = fcoe_ctlr_mtu_valid(fcf); 1047 mtu_valid = fcoe_ctlr_mtu_valid(fcf);
958 fcf->time = jiffies; 1048 fcf->time = jiffies;
959 if (!found) 1049 if (!found)
@@ -996,6 +1086,7 @@ static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb)
996 time_before(fip->sel_time, fip->timer.expires)) 1086 time_before(fip->sel_time, fip->timer.expires))
997 mod_timer(&fip->timer, fip->sel_time); 1087 mod_timer(&fip->timer, fip->sel_time);
998 } 1088 }
1089
999out: 1090out:
1000 mutex_unlock(&fip->ctlr_mutex); 1091 mutex_unlock(&fip->ctlr_mutex);
1001} 1092}
@@ -2718,9 +2809,9 @@ unlock:
2718 2809
2719/** 2810/**
2720 * fcoe_libfc_config() - Sets up libfc related properties for local port 2811 * fcoe_libfc_config() - Sets up libfc related properties for local port
2721 * @lp: The local port to configure libfc for 2812 * @lport: The local port to configure libfc for
2722 * @fip: The FCoE controller in use by the local port 2813 * @fip: The FCoE controller in use by the local port
2723 * @tt: The libfc function template 2814 * @tt: The libfc function template
2724 * @init_fcp: If non-zero, the FCP portion of libfc should be initialized 2815 * @init_fcp: If non-zero, the FCP portion of libfc should be initialized
2725 * 2816 *
2726 * Returns : 0 for success 2817 * Returns : 0 for success
@@ -2753,3 +2844,43 @@ int fcoe_libfc_config(struct fc_lport *lport, struct fcoe_ctlr *fip,
2753 return 0; 2844 return 0;
2754} 2845}
2755EXPORT_SYMBOL_GPL(fcoe_libfc_config); 2846EXPORT_SYMBOL_GPL(fcoe_libfc_config);
2847
2848void fcoe_fcf_get_selected(struct fcoe_fcf_device *fcf_dev)
2849{
2850 struct fcoe_ctlr_device *ctlr_dev = fcoe_fcf_dev_to_ctlr_dev(fcf_dev);
2851 struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr_dev);
2852 struct fcoe_fcf *fcf;
2853
2854 mutex_lock(&fip->ctlr_mutex);
2855 mutex_lock(&ctlr_dev->lock);
2856
2857 fcf = fcoe_fcf_device_priv(fcf_dev);
2858 if (fcf)
2859 fcf_dev->selected = (fcf == fip->sel_fcf) ? 1 : 0;
2860 else
2861 fcf_dev->selected = 0;
2862
2863 mutex_unlock(&ctlr_dev->lock);
2864 mutex_unlock(&fip->ctlr_mutex);
2865}
2866EXPORT_SYMBOL(fcoe_fcf_get_selected);
2867
2868void fcoe_ctlr_get_fip_mode(struct fcoe_ctlr_device *ctlr_dev)
2869{
2870 struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev);
2871
2872 mutex_lock(&ctlr->ctlr_mutex);
2873 switch (ctlr->mode) {
2874 case FIP_MODE_FABRIC:
2875 ctlr_dev->mode = FIP_CONN_TYPE_FABRIC;
2876 break;
2877 case FIP_MODE_VN2VN:
2878 ctlr_dev->mode = FIP_CONN_TYPE_VN2VN;
2879 break;
2880 default:
2881 ctlr_dev->mode = FIP_CONN_TYPE_UNKNOWN;
2882 break;
2883 }
2884 mutex_unlock(&ctlr->ctlr_mutex);
2885}
2886EXPORT_SYMBOL(fcoe_ctlr_get_fip_mode);