20 #include <linux/module.h>
22 #include <linux/netdevice.h>
24 #include <linux/ethtool.h>
25 #include <linux/if_ether.h>
26 #include <linux/if_vlan.h>
28 #include <linux/slab.h>
32 #include <linux/ctype.h>
57 static unsigned int fcoe_ddp_min = 4096;
60 "Direct Data Placement (DDP).");
79 static int fcoe_reset(
struct Scsi_Host *);
83 static int fcoe_percpu_receive_thread(
void *);
84 static void fcoe_percpu_clean(
struct fc_lport *);
85 static int fcoe_link_speed_update(
struct fc_lport *);
86 static int fcoe_link_ok(
struct fc_lport *);
89 static int fcoe_hostlist_add(
const struct fc_lport *);
92 static void fcoe_dev_setup(
void);
93 static void fcoe_dev_cleanup(
void);
95 *fcoe_hostlist_lookup_port(
const struct net_device *);
101 static void fcoe_update_src_mac(
struct fc_lport *,
u8 *);
102 static u8 *fcoe_get_src_mac(
struct fc_lport *);
103 static void fcoe_destroy_work(
struct work_struct *);
110 static int fcoe_cpu_callback(
struct notifier_block *,
unsigned long,
void *);
111 static int fcoe_dcb_app_notification(
struct notifier_block *notifier,
126 void *,
u32 timeout);
127 static void fcoe_recv_frame(
struct sk_buff *
skb);
133 .notifier_call = fcoe_device_notification,
138 .notifier_call = fcoe_cpu_callback,
143 .notifier_call = fcoe_dcb_app_notification,
149 static int fcoe_vport_destroy(
struct fc_vport *);
150 static int fcoe_vport_create(
struct fc_vport *,
bool disabled);
152 static void fcoe_set_vport_symbolic_name(
struct fc_vport *);
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,
167 .get_fcoe_fcf_vlan_id = fcoe_fcf_get_vlan_id,
171 .frame_send = fcoe_xmit,
172 .ddp_setup = fcoe_ddp_setup,
173 .ddp_done = fcoe_ddp_done,
174 .ddp_target = fcoe_ddp_target,
175 .elsct_send = fcoe_elsct_send,
176 .get_lesb = fcoe_get_lesb,
177 .lport_set_port_id = fcoe_set_port_id,
181 .show_host_node_name = 1,
182 .show_host_port_name = 1,
183 .show_host_supported_classes = 1,
184 .show_host_supported_fc4s = 1,
185 .show_host_active_fc4s = 1,
186 .show_host_maxframe_size = 1,
187 .show_host_serial_number = 1,
188 .show_host_manufacturer = 1,
189 .show_host_model = 1,
190 .show_host_model_description = 1,
191 .show_host_hardware_version = 1,
192 .show_host_driver_version = 1,
193 .show_host_firmware_version = 1,
194 .show_host_optionrom_version = 1,
196 .show_host_port_id = 1,
197 .show_host_supported_speeds = 1,
199 .show_host_speed = 1,
200 .show_host_port_type = 1,
202 .show_host_port_state = 1,
203 .show_host_symbolic_name = 1,
206 .show_rport_maxframe_size = 1,
207 .show_rport_supported_classes = 1,
209 .show_host_fabric_name = 1,
210 .show_starget_node_name = 1,
211 .show_starget_port_name = 1,
212 .show_starget_port_id = 1,
214 .show_rport_dev_loss_tmo = 1,
216 .issue_fc_host_lip = fcoe_reset,
220 .vport_create = fcoe_vport_create,
221 .vport_delete = fcoe_vport_destroy,
222 .vport_disable = fcoe_vport_disable,
223 .set_vport_symbolic_name = fcoe_set_vport_symbolic_name,
229 .show_host_node_name = 1,
230 .show_host_port_name = 1,
231 .show_host_supported_classes = 1,
232 .show_host_supported_fc4s = 1,
233 .show_host_active_fc4s = 1,
234 .show_host_maxframe_size = 1,
235 .show_host_serial_number = 1,
236 .show_host_manufacturer = 1,
237 .show_host_model = 1,
238 .show_host_model_description = 1,
239 .show_host_hardware_version = 1,
240 .show_host_driver_version = 1,
241 .show_host_firmware_version = 1,
242 .show_host_optionrom_version = 1,
244 .show_host_port_id = 1,
245 .show_host_supported_speeds = 1,
247 .show_host_speed = 1,
248 .show_host_port_type = 1,
250 .show_host_port_state = 1,
251 .show_host_symbolic_name = 1,
254 .show_rport_maxframe_size = 1,
255 .show_rport_supported_classes = 1,
257 .show_host_fabric_name = 1,
258 .show_starget_node_name = 1,
259 .show_starget_port_name = 1,
260 .show_starget_port_id = 1,
262 .show_rport_dev_loss_tmo = 1,
264 .issue_fc_host_lip = fcoe_reset,
273 .name =
"FCoE Driver",
287 .max_sectors = 0xffff,
311 if (ops->ndo_fcoe_enable) {
312 if (ops->ndo_fcoe_enable(netdev))
314 " specific feature for LLD.\n");
331 (is_valid_ether_addr(ha->
addr))) {
393 "Could not get a reference to the module\n");
394 fcoe = ERR_PTR(-
EBUSY);
402 FCOE_DBG(
"Failed to add fcoe_ctlr_device\n");
407 ctlr = fcoe_ctlr_device_priv(ctlr_dev);
408 fcoe = fcoe_ctlr_priv(ctlr);
416 ctlr->
send = fcoe_fip_send;
420 err = fcoe_interface_setup(fcoe, netdev);
473 if (ops->ndo_fcoe_disable) {
474 if (ops->ndo_fcoe_disable(netdev))
476 " specific feature for LLD.\n");
494 fcoe_interface_remove(fcoe);
550 fcoe_port_send(lport_priv(fip->
lp), skb);
563 struct fcoe_port *port = lport_priv(lport);
568 if (!is_zero_ether_addr(addr))
577 static u8 *fcoe_get_src_mac(
struct fc_lport *lport)
579 struct fcoe_port *port = lport_priv(lport);
590 static int fcoe_lport_config(
struct fc_lport *lport)
602 fc_lport_init_stats(lport);
621 static void fcoe_netdev_features_change(
struct fc_lport *lport,
648 if (netdev->fcoe_ddp_xid) {
650 lport->
lro_xid = netdev->fcoe_ddp_xid;
679 port = lport_priv(lport);
698 fcoe_netdev_features_change(lport, netdev);
704 fcoe_link_speed_update(lport);
709 fc_set_wwnn(lport, wwnn);
713 fc_set_wwpn(lport, wwpn);
735 lport->
host->max_channel = 0;
739 lport->
host->transportt = fcoe_vport_scsi_transport;
741 lport->
host->transportt = fcoe_nport_scsi_transport;
744 rc = scsi_add_host(lport->
host, dev);
747 "error on scsi_add_host\n");
756 fcoe_netdev(lport)->
name);
776 struct netdev_fcoe_hbainfo fdmi;
778 port = lport_priv(lport);
789 if (realdev->
netdev_ops->ndo_fcoe_get_hbainfo) {
790 memset(&fdmi, 0,
sizeof(fdmi));
791 rc = realdev->
netdev_ops->ndo_fcoe_get_hbainfo(realdev,
795 "information from netdev.\n");
814 fdmi.model_description);
818 fdmi.hardware_version);
822 fdmi.driver_version);
826 fdmi.optionrom_version);
830 fdmi.firmware_version);
858 static bool fcoe_oem_match(
struct fc_frame *
fp)
863 if (fc_fcp_is_read(
fr_fsp(fp)) &&
869 fcp = fc_frame_payload_get(fp,
sizeof(*fcp));
883 static inline int fcoe_em_config(
struct fc_lport *lport)
885 struct fcoe_port *port = lport_priv(lport);
888 struct net_device *old_real_dev, *cur_real_dev;
909 cur_real_dev = fcoe->
netdev;
915 old_real_dev = oldfcoe->
netdev;
917 if (cur_real_dev == old_real_dev) {
926 "offload em:%p on interface:%s\n",
936 "em for offload exches on interface:%s\n",
950 "allocate em on interface %s\n", fcoe->
netdev->name);
962 static void fcoe_if_destroy(
struct fc_lport *lport)
964 struct fcoe_port *port = lport_priv(lport);
988 fcoe_interface_remove(fcoe);
992 fcoe_percpu_clean(lport);
1005 fc_lport_free_stats(lport);
1027 struct net_device *netdev = fcoe_netdev(lport);
1030 return netdev->
netdev_ops->ndo_fcoe_ddp_setup(netdev,
1046 static int fcoe_ddp_target(
struct fc_lport *lport,
u16 xid,
1049 struct net_device *netdev = fcoe_netdev(lport);
1052 return netdev->
netdev_ops->ndo_fcoe_ddp_target(netdev, xid,
1066 static int fcoe_ddp_done(
struct fc_lport *lport,
u16 xid)
1068 struct net_device *netdev = fcoe_netdev(lport);
1071 return netdev->
netdev_ops->ndo_fcoe_ddp_done(netdev, xid);
1086 struct device *parent,
int npiv)
1103 lport = libfc_host_alloc(&fcoe_shost_template,
sizeof(*port));
1112 port = lport_priv(lport);
1120 rc = fcoe_lport_config(lport);
1129 "%16.16llx %16.16llx\n",
1136 rc = fcoe_netdev_config(lport, netdev);
1140 goto out_lp_destroy;
1144 rc = fcoe_shost_config(lport, parent);
1148 goto out_lp_destroy;
1156 goto out_lp_destroy;
1160 fcoe_fdmi_info(lport, netdev);
1173 rc = fcoe_em_config(lport);
1176 n_port = shost_priv(shost);
1182 goto out_lp_destroy;
1202 static int __init fcoe_if_init(
void)
1205 fcoe_nport_scsi_transport =
1207 fcoe_vport_scsi_transport =
1210 if (!fcoe_nport_scsi_transport) {
1225 static int __exit fcoe_if_exit(
void)
1229 fcoe_nport_scsi_transport =
NULL;
1230 fcoe_vport_scsi_transport =
NULL;
1238 static void fcoe_percpu_thread_create(
unsigned int cpu)
1243 p = &
per_cpu(fcoe_percpu, cpu);
1247 "fcoethread/%d", cpu);
1249 if (
likely(!IS_ERR(thread))) {
1267 static void fcoe_percpu_thread_destroy(
unsigned int cpu)
1271 struct page *crc_eof;
1275 unsigned targ_cpu =
get_cpu();
1278 FCOE_DBG(
"Destroying receive thread for CPU %d\n", cpu);
1281 p = &
per_cpu(fcoe_percpu, cpu);
1296 if (cpu != targ_cpu) {
1297 p0 = &
per_cpu(fcoe_percpu, targ_cpu);
1300 FCOE_DBG(
"Moving frames from CPU %d to CPU %d\n",
1361 unsigned long action,
void *hcpu)
1363 unsigned cpu = (
unsigned long)hcpu;
1368 FCOE_DBG(
"CPU %x online: Create Rx thread\n", cpu);
1369 fcoe_percpu_thread_create(cpu);
1373 FCOE_DBG(
"CPU %x offline: Remove Rx thread\n", cpu);
1374 fcoe_percpu_thread_destroy(cpu);
1391 static inline unsigned int fcoe_select_cpu(
void)
1393 static unsigned int selected_cpu;
1395 selected_cpu = cpumask_next(selected_cpu, cpu_online_mask);
1396 if (selected_cpu >= nr_cpu_ids)
1397 selected_cpu = cpumask_first(cpu_online_mask);
1399 return selected_cpu;
1437 "data:%p tail:%p end:%p sum:%d dev:%s",
1439 skb_tail_pointer(skb), skb_end_pointer(skb),
1440 skb->
csum, skb->
dev ? skb->
dev->name :
"<NULL>");
1444 if (is_fip_mode(ctlr) &&
1459 skb_set_transport_header(skb,
sizeof(
struct fcoe_hdr));
1468 fr = fcoe_dev_from_skb(skb);
1482 cpu = fcoe_select_cpu();
1487 if (cpu >= nr_cpu_ids)
1490 fps = &
per_cpu(fcoe_percpu, cpu);
1499 "ready for incoming skb- using first online "
1503 cpu = cpumask_first(cpu_online_mask);
1504 fps = &
per_cpu(fcoe_percpu, cpu);
1546 static int fcoe_alloc_paged_crc_eof(
struct sk_buff *skb,
int tlen)
1577 struct fcoe_port *port = lport_priv(lport);
1585 fh = fc_frame_header_get(fp);
1601 elen =
sizeof(
struct ethhdr);
1618 if (skb_is_nonlinear(skb)) {
1620 if (fcoe_alloc_paged_crc_eof(skb, tlen)) {
1624 frag = &skb_shinfo(skb)->frags[skb_shinfo(skb)->nr_frags - 1];
1631 memset(cp, 0,
sizeof(*cp));
1635 if (skb_is_nonlinear(skb)) {
1642 skb_reset_mac_header(skb);
1643 skb_reset_network_header(skb);
1669 memset(hp, 0,
sizeof(*hp));
1679 skb_shinfo(skb)->gso_type = 0;
1680 skb_shinfo(skb)->gso_size = 0;
1690 fcoe_port_send(port, skb);
1698 static void fcoe_percpu_flush_done(
struct sk_buff *skb)
1710 static inline int fcoe_filter_frames(
struct fc_lport *lport,
1730 fh = fc_frame_header_get(fp);
1736 if (is_fip_mode(ctlr) && fc_frame_payload_op(fp) ==
ELS_LOGO &&
1738 FCOE_DBG(
"fcoe: dropping FCoE lport LOGO in fip mode\n");
1744 fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED;
1760 static void fcoe_recv_frame(
struct sk_buff *skb)
1771 fr = fcoe_dev_from_skb(skb);
1774 if (skb->
destructor != fcoe_percpu_flush_done)
1781 "head:%p data:%p tail:%p end:%p sum:%d dev:%s",
1783 skb->
head, skb->
data, skb_tail_pointer(skb),
1784 skb_end_pointer(skb), skb->
csum,
1785 skb->
dev ? skb->
dev->name :
"<NULL>");
1787 port = lport_priv(lport);
1794 hp = (
struct fcoe_hdr *) skb_network_header(skb);
1800 "mismatch: The frame has "
1801 "version %x, but the "
1802 "initiator supports version "
1822 fr_eof(fp) = crc_eof.fcoe_eof;
1823 fr_crc(fp) = crc_eof.fcoe_crc32;
1824 if (pskb_trim(skb, fr_len))
1827 if (!fcoe_filter_frames(lport, fp)) {
1844 static int fcoe_percpu_receive_thread(
void *
arg)
1850 skb_queue_head_init(&
tmp);
1860 if (!skb_queue_len(&
tmp)) {
1870 while ((skb = __skb_dequeue(&
tmp)) !=
NULL)
1871 fcoe_recv_frame(skb);
1880 static void fcoe_dev_setup(
void)
1889 static void fcoe_dev_cleanup(
void)
1896 fcoe_hostlist_lookup_realdev_port(
struct net_device *netdev)
1907 if (netdev == real_dev)
1913 static int fcoe_dcb_app_notification(
struct notifier_block *notifier,
1929 fcoe = fcoe_hostlist_lookup_realdev_port(netdev);
1937 prio =
ffs(entry->
app.priority) - 1;
1939 prio = entry->
app.priority;
1964 static int fcoe_device_notification(
struct notifier_block *notifier,
1965 ulong event,
void *ptr)
1973 u32 link_possible = 1;
1978 if (fcoe->
netdev == netdev) {
2009 port = lport_priv(ctlr->
lp);
2014 fcoe_netdev_features_change(lport, netdev);
2018 "from netdev netlink\n", event);
2021 fcoe_link_speed_update(lport);
2023 if (link_possible && !fcoe_link_ok(lport))
2043 static int fcoe_disable(
struct net_device *netdev)
2052 fcoe = fcoe_hostlist_lookup_port(netdev);
2074 static int fcoe_enable(
struct net_device *netdev)
2082 fcoe = fcoe_hostlist_lookup_port(netdev);
2092 if (!fcoe_link_ok(ctlr->
lp))
2108 static int fcoe_destroy(
struct net_device *netdev)
2118 fcoe = fcoe_hostlist_lookup_port(netdev);
2125 port = lport_priv(lport);
2147 fcoe_if_destroy(port->
lport);
2148 fcoe_interface_cleanup(fcoe);
2162 static bool fcoe_match(
struct net_device *netdev)
2186 if (netdev && netdev->dcbnl_ops && netdev->dcbnl_ops->getdcbx) {
2187 dcbx = netdev->dcbnl_ops->getdcbx(netdev);
2228 if (fcoe_hostlist_lookup(netdev)) {
2233 fcoe = fcoe_interface_create(netdev, fip_mode);
2241 lport = fcoe_if_create(fcoe, &ctlr_dev->
dev, 0);
2242 if (IS_ERR(lport)) {
2247 fcoe_interface_cleanup(fcoe);
2255 fcoe_dcb_create(fcoe);
2258 fcoe_hostlist_add(lport);
2263 if (!fcoe_link_ok(lport)) {
2284 static int fcoe_link_speed_update(
struct fc_lport *lport)
2286 struct net_device *netdev = fcoe_netdev(lport);
2298 switch (ethtool_cmd_speed(&ecmd)) {
2318 static int fcoe_link_ok(
struct fc_lport *lport)
2320 struct net_device *netdev = fcoe_netdev(lport);
2322 if (netif_oper_up(netdev))
2338 static void fcoe_percpu_clean(
struct fc_lport *lport)
2345 pp = &
per_cpu(fcoe_percpu, cpu);
2350 skb = dev_alloc_skb(0);
2372 static int fcoe_reset(
struct Scsi_Host *shost)
2374 struct fc_lport *lport = shost_priv(shost);
2375 struct fcoe_port *port = lport_priv(lport);
2381 if (!fcoe_link_ok(ctlr->
lp))
2395 fcoe_hostlist_lookup_port(
const struct net_device *netdev)
2400 if (fcoe->
netdev == netdev)
2420 fcoe = fcoe_hostlist_lookup_port(netdev);
2422 return (fcoe) ? ctlr->
lp :
NULL;
2434 static int fcoe_hostlist_add(
const struct fc_lport *lport)
2439 fcoe = fcoe_hostlist_lookup_port(fcoe_netdev(lport));
2441 port = lport_priv(lport);
2453 .match = fcoe_match,
2454 .create = fcoe_create,
2455 .destroy = fcoe_destroy,
2456 .enable = fcoe_enable,
2457 .disable = fcoe_disable,
2465 static int __init fcoe_init(
void)
2479 "if libfcoe is loaded\n");
2486 p = &
per_cpu(fcoe_percpu, cpu);
2491 fcoe_percpu_thread_create(cpu);
2501 rc = fcoe_if_init();
2510 fcoe_percpu_thread_destroy(cpu);
2523 static void __exit fcoe_exit(
void)
2539 port = lport_priv(ctlr->
lp);
2547 fcoe_percpu_thread_destroy(cpu);
2588 mac =
fr_cb(fp)->granted_mac;
2590 if (is_zero_ether_addr(mac))
2592 if (!is_zero_ether_addr(mac))
2593 fcoe_update_src_mac(lport, mac);
2607 static void fcoe_logo_resp(
struct fc_seq *seq,
struct fc_frame *fp,
void *arg)
2613 fcoe_update_src_mac(lport, zero_mac);
2627 struct fc_frame *fp,
unsigned int op,
2631 void *arg,
u32 timeout)
2633 struct fcoe_port *port = lport_priv(lport);
2662 static int fcoe_vport_create(
struct fc_vport *vport,
bool disabled)
2665 struct fc_lport *n_port = shost_priv(shost);
2666 struct fcoe_port *port = lport_priv(n_port);
2677 "WWPN (0x%s) already exists\n",
2684 vn_port = fcoe_if_create(fcoe, &vport->
dev, 1);
2688 if (IS_ERR(vn_port)) {
2710 static int fcoe_vport_destroy(
struct fc_vport *vport)
2713 struct fc_lport *n_port = shost_priv(shost);
2721 fcoe_if_destroy(vn_port);
2756 static void fcoe_set_vport_symbolic_name(
struct fc_vport *vport)
2770 fp = fc_frame_alloc(lport,
2784 static void fcoe_get_lesb(
struct fc_lport *lport,
2787 struct net_device *netdev = fcoe_netdev(lport);
2794 struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr_dev);
2802 ctlr_dev->
lesb.lesb_link_fail =
2804 ctlr_dev->
lesb.lesb_vlink_fail =
2806 ctlr_dev->
lesb.lesb_miss_fka =
2808 ctlr_dev->
lesb.lesb_symb_err =
2810 ctlr_dev->
lesb.lesb_err_block =
2812 ctlr_dev->
lesb.lesb_fcs_error =
2820 struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev);
2838 static void fcoe_set_port_id(
struct fc_lport *lport,
2841 struct fcoe_port *port = lport_priv(lport);
2845 if (fp && fc_frame_payload_op(fp) ==
ELS_FLOGI)