diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2017-07-26 14:23:10 +0300 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2017-07-26 14:43:33 +0300 |
commit | af055598542670c8533a58582813b1419949cae0 (patch) | |
tree | 901fa1bf635d5c1e91d08f9f4c2e4943516dbb71 /drivers/scsi/bnx2fc/bnx2fc_fcoe.c | |
parent | 9f15a4ab19ab33658dbc9fd37be5210e8c1ac622 (diff) | |
parent | 2d62c799f8ffac4f7ffba6a4e7f148827dfc24c7 (diff) | |
download | linux-af055598542670c8533a58582813b1419949cae0.tar.xz |
Merge airlied/drm-next into drm-misc-next
I need this to be able to apply the deferred fbdev setup patches, I
need the relevant prep work that landed through the drm-intel tree.
Also squash in conflict fixup from Laurent Pinchart.
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/scsi/bnx2fc/bnx2fc_fcoe.c')
-rw-r--r-- | drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 64 |
1 files changed, 59 insertions, 5 deletions
diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index 902722dc4ce3..7dfe709a7138 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c @@ -4,7 +4,8 @@ * FIP/FCoE packets, listen to link events etc. * * Copyright (c) 2008-2013 Broadcom Corporation - * Copyright (c) 2014-2015 QLogic Corporation + * Copyright (c) 2014-2016 QLogic Corporation + * Copyright (c) 2016-2017 Cavium Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -351,7 +352,7 @@ static int bnx2fc_xmit(struct fc_lport *lport, struct fc_frame *fp) frag = &skb_shinfo(skb)->frags[skb_shinfo(skb)->nr_frags - 1]; cp = kmap_atomic(skb_frag_page(frag)) + frag->page_offset; } else { - cp = (struct fcoe_crc_eof *)skb_put(skb, tlen); + cp = skb_put(skb, tlen); } memset(cp, 0, sizeof(*cp)); @@ -522,10 +523,12 @@ static void bnx2fc_recv_frame(struct sk_buff *skb) struct fcoe_crc_eof crc_eof; struct fc_frame *fp; struct fc_lport *vn_port; - struct fcoe_port *port; + struct fcoe_port *port, *phys_port; u8 *mac = NULL; u8 *dest_mac = NULL; struct fcoe_hdr *hp; + struct bnx2fc_interface *interface; + struct fcoe_ctlr *ctlr; fr = fcoe_dev_from_skb(skb); lport = fr->fr_dev; @@ -561,8 +564,19 @@ static void bnx2fc_recv_frame(struct sk_buff *skb) return; } + phys_port = lport_priv(lport); + interface = phys_port->priv; + ctlr = bnx2fc_to_ctlr(interface); + fh = fc_frame_header_get(fp); + if (ntoh24(&dest_mac[3]) != ntoh24(fh->fh_d_id)) { + BNX2FC_HBA_DBG(lport, "FC frame d_id mismatch with MAC %pM.\n", + dest_mac); + kfree_skb(skb); + return; + } + vn_port = fc_vport_id_lookup(lport, ntoh24(fh->fh_d_id)); if (vn_port) { port = lport_priv(vn_port); @@ -572,6 +586,14 @@ static void bnx2fc_recv_frame(struct sk_buff *skb) return; } } + if (ctlr->state) { + if (!ether_addr_equal(mac, ctlr->dest_addr)) { + BNX2FC_HBA_DBG(lport, "Wrong source address: mac:%pM dest_addr:%pM.\n", + mac, ctlr->dest_addr); + kfree_skb(skb); + return; + } + } if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA && fh->fh_type == FC_TYPE_FCP) { /* Drop FCP data. We dont this in L2 path */ @@ -597,6 +619,18 @@ static void bnx2fc_recv_frame(struct sk_buff *skb) return; } + /* + * If the destination ID from the frame header does not match what we + * have on record for lport and the search for a NPIV port came up + * empty then this is not addressed to our port so simply drop it. + */ + if (lport->port_id != ntoh24(fh->fh_d_id) && !vn_port) { + BNX2FC_HBA_DBG(lport, "Dropping frame due to destination mismatch: lport->port_id=%x fh->d_id=%x.\n", + lport->port_id, ntoh24(fh->fh_d_id)); + kfree_skb(skb); + return; + } + stats = per_cpu_ptr(lport->stats, smp_processor_id()); stats->RxFrames++; stats->RxWords += fr_len / FCOE_WORD_TO_BYTE; @@ -2105,6 +2139,9 @@ static uint bnx2fc_npiv_create_vports(struct fc_lport *lport, { struct fc_vport_identifiers vpid; uint i, created = 0; + u64 wwnn = 0; + char wwpn_str[32]; + char wwnn_str[32]; if (npiv_tbl->count > MAX_NPIV_ENTRIES) { BNX2FC_HBA_DBG(lport, "Exceeded count max of npiv table\n"); @@ -2123,11 +2160,23 @@ static uint bnx2fc_npiv_create_vports(struct fc_lport *lport, vpid.disable = false; for (i = 0; i < npiv_tbl->count; i++) { - vpid.node_name = wwn_to_u64(npiv_tbl->wwnn[i]); + wwnn = wwn_to_u64(npiv_tbl->wwnn[i]); + if (wwnn == 0) { + /* + * If we get a 0 element from for the WWNN then assume + * the WWNN should be the same as the physical port. + */ + wwnn = lport->wwnn; + } + vpid.node_name = wwnn; vpid.port_name = wwn_to_u64(npiv_tbl->wwpn[i]); scnprintf(vpid.symbolic_name, sizeof(vpid.symbolic_name), "NPIV[%u]:%016llx-%016llx", created, vpid.port_name, vpid.node_name); + fcoe_wwn_to_str(vpid.node_name, wwnn_str, sizeof(wwnn_str)); + fcoe_wwn_to_str(vpid.port_name, wwpn_str, sizeof(wwpn_str)); + BNX2FC_HBA_DBG(lport, "Creating vport %s:%s.\n", wwnn_str, + wwpn_str); if (fc_vport_create(lport->host, 0, &vpid)) created++; else @@ -2524,6 +2573,11 @@ static void bnx2fc_ulp_exit(struct cnic_dev *dev) bnx2fc_hba_destroy(hba); } +static void bnx2fc_rport_terminate_io(struct fc_rport *rport) +{ + /* This is a no-op */ +} + /** * bnx2fc_fcoe_reset - Resets the fcoe * @@ -2860,7 +2914,7 @@ static struct fc_function_template bnx2fc_transport_function = { .issue_fc_host_lip = bnx2fc_fcoe_reset, - .terminate_rport_io = fc_rport_terminate_io, + .terminate_rport_io = bnx2fc_rport_terminate_io, .vport_create = bnx2fc_vport_create, .vport_delete = bnx2fc_vport_destroy, |