Commit 323f6226 authored by James Bottomley's avatar James Bottomley

Merge tag 'fcoe-3.13' into for-linus

Pull Request for 3.13 for FCOE tree.
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parents 6fd046f9 6942df7f
......@@ -542,8 +542,7 @@ static void bnx2fc_recv_frame(struct sk_buff *skb)
vn_port = fc_vport_id_lookup(lport, ntoh24(fh->fh_d_id));
if (vn_port) {
port = lport_priv(vn_port);
if (compare_ether_addr(port->data_src_addr, dest_mac)
!= 0) {
if (!ether_addr_equal(port->data_src_addr, dest_mac)) {
BNX2FC_HBA_DBG(lport, "fpma mismatch\n");
put_cpu();
kfree_skb(skb);
......@@ -1381,6 +1380,7 @@ struct bnx2fc_interface *bnx2fc_interface_create(struct bnx2fc_hba *hba,
return NULL;
}
ctlr = fcoe_ctlr_device_priv(ctlr_dev);
ctlr->cdev = ctlr_dev;
interface = fcoe_ctlr_priv(ctlr);
dev_hold(netdev);
kref_init(&interface->kref);
......
......@@ -408,6 +408,7 @@ static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev,
}
ctlr = fcoe_ctlr_device_priv(ctlr_dev);
ctlr->cdev = ctlr_dev;
fcoe = fcoe_ctlr_priv(ctlr);
dev_hold(netdev);
......@@ -1440,22 +1441,28 @@ static int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev,
ctlr = fcoe_to_ctlr(fcoe);
lport = ctlr->lp;
if (unlikely(!lport)) {
FCOE_NETDEV_DBG(netdev, "Cannot find hba structure");
FCOE_NETDEV_DBG(netdev, "Cannot find hba structure\n");
goto err2;
}
if (!lport->link_up)
goto err2;
FCOE_NETDEV_DBG(netdev, "skb_info: len:%d data_len:%d head:%p "
"data:%p tail:%p end:%p sum:%d dev:%s",
FCOE_NETDEV_DBG(netdev,
"skb_info: len:%d data_len:%d head:%p data:%p tail:%p end:%p sum:%d dev:%s\n",
skb->len, skb->data_len, skb->head, skb->data,
skb_tail_pointer(skb), skb_end_pointer(skb),
skb->csum, skb->dev ? skb->dev->name : "<NULL>");
skb = skb_share_check(skb, GFP_ATOMIC);
if (skb == NULL)
return NET_RX_DROP;
eh = eth_hdr(skb);
if (is_fip_mode(ctlr) &&
compare_ether_addr(eh->h_source, ctlr->dest_addr)) {
!ether_addr_equal(eh->h_source, ctlr->dest_addr)) {
FCOE_NETDEV_DBG(netdev, "wrong source mac address:%pM\n",
eh->h_source);
goto err;
......@@ -1540,13 +1547,13 @@ static int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev,
wake_up_process(fps->thread);
spin_unlock(&fps->fcoe_rx_list.lock);
return 0;
return NET_RX_SUCCESS;
err:
per_cpu_ptr(lport->stats, get_cpu())->ErrorFrames++;
put_cpu();
err2:
kfree_skb(skb);
return -1;
return NET_RX_DROP;
}
/**
......@@ -1788,13 +1795,13 @@ static void fcoe_recv_frame(struct sk_buff *skb)
lport = fr->fr_dev;
if (unlikely(!lport)) {
if (skb->destructor != fcoe_percpu_flush_done)
FCOE_NETDEV_DBG(skb->dev, "NULL lport in skb");
FCOE_NETDEV_DBG(skb->dev, "NULL lport in skb\n");
kfree_skb(skb);
return;
}
FCOE_NETDEV_DBG(skb->dev, "skb_info: len:%d data_len:%d "
"head:%p data:%p tail:%p end:%p sum:%d dev:%s",
FCOE_NETDEV_DBG(skb->dev,
"skb_info: len:%d data_len:%d head:%p data:%p tail:%p end:%p sum:%d dev:%s\n",
skb->len, skb->data_len,
skb->head, skb->data, skb_tail_pointer(skb),
skb_end_pointer(skb), skb->csum,
......
......@@ -160,74 +160,113 @@ void fcoe_ctlr_init(struct fcoe_ctlr *fip, enum fip_state mode)
}
EXPORT_SYMBOL(fcoe_ctlr_init);
/**
* fcoe_sysfs_fcf_add() - Add a fcoe_fcf{,_device} to a fcoe_ctlr{,_device}
* @new: The newly discovered FCF
*
* Called with fip->ctlr_mutex held
*/
static int fcoe_sysfs_fcf_add(struct fcoe_fcf *new)
{
struct fcoe_ctlr *fip = new->fip;
struct fcoe_ctlr_device *ctlr_dev = fcoe_ctlr_to_ctlr_dev(fip);
struct fcoe_fcf_device temp, *fcf_dev;
int rc = 0;
struct fcoe_ctlr_device *ctlr_dev;
struct fcoe_fcf_device *temp, *fcf_dev;
int rc = -ENOMEM;
LIBFCOE_FIP_DBG(fip, "New FCF fab %16.16llx mac %pM\n",
new->fabric_name, new->fcf_mac);
mutex_lock(&ctlr_dev->lock);
temp.fabric_name = new->fabric_name;
temp.switch_name = new->switch_name;
temp.fc_map = new->fc_map;
temp.vfid = new->vfid;
memcpy(temp.mac, new->fcf_mac, ETH_ALEN);
temp.priority = new->pri;
temp.fka_period = new->fka_period;
temp.selected = 0; /* default to unselected */
fcf_dev = fcoe_fcf_device_add(ctlr_dev, &temp);
if (unlikely(!fcf_dev)) {
rc = -ENOMEM;
temp = kzalloc(sizeof(*temp), GFP_KERNEL);
if (!temp)
goto out;
}
temp->fabric_name = new->fabric_name;
temp->switch_name = new->switch_name;
temp->fc_map = new->fc_map;
temp->vfid = new->vfid;
memcpy(temp->mac, new->fcf_mac, ETH_ALEN);
temp->priority = new->pri;
temp->fka_period = new->fka_period;
temp->selected = 0; /* default to unselected */
/*
* The fcoe_sysfs layer can return a CONNECTED fcf that
* has a priv (fcf was never deleted) or a CONNECTED fcf
* that doesn't have a priv (fcf was deleted). However,
* libfcoe will always delete FCFs before trying to add
* them. This is ensured because both recv_adv and
* age_fcfs are protected by the the fcoe_ctlr's mutex.
* This means that we should never get a FCF with a
* non-NULL priv pointer.
* If ctlr_dev doesn't exist then it means we're a libfcoe user
* who doesn't use fcoe_syfs and didn't allocate a fcoe_ctlr_device.
* fnic would be an example of a driver with this behavior. In this
* case we want to add the fcoe_fcf to the fcoe_ctlr list, but we
* don't want to make sysfs changes.
*/
BUG_ON(fcf_dev->priv);
fcf_dev->priv = new;
new->fcf_dev = fcf_dev;
ctlr_dev = fcoe_ctlr_to_ctlr_dev(fip);
if (ctlr_dev) {
mutex_lock(&ctlr_dev->lock);
fcf_dev = fcoe_fcf_device_add(ctlr_dev, temp);
if (unlikely(!fcf_dev)) {
rc = -ENOMEM;
mutex_unlock(&ctlr_dev->lock);
goto out;
}
/*
* The fcoe_sysfs layer can return a CONNECTED fcf that
* has a priv (fcf was never deleted) or a CONNECTED fcf
* that doesn't have a priv (fcf was deleted). However,
* libfcoe will always delete FCFs before trying to add
* them. This is ensured because both recv_adv and
* age_fcfs are protected by the the fcoe_ctlr's mutex.
* This means that we should never get a FCF with a
* non-NULL priv pointer.
*/
BUG_ON(fcf_dev->priv);
fcf_dev->priv = new;
new->fcf_dev = fcf_dev;
mutex_unlock(&ctlr_dev->lock);
}
list_add(&new->list, &fip->fcfs);
fip->fcf_count++;
rc = 0;
out:
mutex_unlock(&ctlr_dev->lock);
kfree(temp);
return rc;
}
/**
* fcoe_sysfs_fcf_del() - Remove a fcoe_fcf{,_device} to a fcoe_ctlr{,_device}
* @new: The FCF to be removed
*
* Called with fip->ctlr_mutex held
*/
static void fcoe_sysfs_fcf_del(struct fcoe_fcf *new)
{
struct fcoe_ctlr *fip = new->fip;
struct fcoe_ctlr_device *ctlr_dev = fcoe_ctlr_to_ctlr_dev(fip);
struct fcoe_ctlr_device *cdev;
struct fcoe_fcf_device *fcf_dev;
list_del(&new->list);
fip->fcf_count--;
mutex_lock(&ctlr_dev->lock);
fcf_dev = fcoe_fcf_to_fcf_dev(new);
WARN_ON(!fcf_dev);
new->fcf_dev = NULL;
fcoe_fcf_device_delete(fcf_dev);
kfree(new);
mutex_unlock(&ctlr_dev->lock);
/*
* If ctlr_dev doesn't exist then it means we're a libfcoe user
* who doesn't use fcoe_syfs and didn't allocate a fcoe_ctlr_device
* or a fcoe_fcf_device.
*
* fnic would be an example of a driver with this behavior. In this
* case we want to remove the fcoe_fcf from the fcoe_ctlr list (above),
* but we don't want to make sysfs changes.
*/
cdev = fcoe_ctlr_to_ctlr_dev(fip);
if (cdev) {
mutex_lock(&cdev->lock);
fcf_dev = fcoe_fcf_to_fcf_dev(new);
WARN_ON(!fcf_dev);
new->fcf_dev = NULL;
fcoe_fcf_device_delete(fcf_dev);
kfree(new);
mutex_unlock(&cdev->lock);
}
}
/**
......@@ -300,7 +339,7 @@ static void fcoe_ctlr_announce(struct fcoe_ctlr *fip)
spin_unlock_bh(&fip->ctlr_lock);
sel = fip->sel_fcf;
if (sel && !compare_ether_addr(sel->fcf_mac, fip->dest_addr))
if (sel && ether_addr_equal(sel->fcf_mac, fip->dest_addr))
goto unlock;
if (!is_zero_ether_addr(fip->dest_addr)) {
printk(KERN_NOTICE "libfcoe: host%d: "
......@@ -1000,7 +1039,7 @@ static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb)
if (fcf->switch_name == new.switch_name &&
fcf->fabric_name == new.fabric_name &&
fcf->fc_map == new.fc_map &&
compare_ether_addr(fcf->fcf_mac, new.fcf_mac) == 0) {
ether_addr_equal(fcf->fcf_mac, new.fcf_mac)) {
found = 1;
break;
}
......@@ -1340,7 +1379,7 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip,
mp = (struct fip_mac_desc *)desc;
if (dlen < sizeof(*mp))
goto err;
if (compare_ether_addr(mp->fd_mac, fcf->fcf_mac))
if (!ether_addr_equal(mp->fd_mac, fcf->fcf_mac))
goto err;
desc_mask &= ~BIT(FIP_DT_MAC);
break;
......@@ -1418,8 +1457,8 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip,
* 'port_id' is already validated, check MAC address and
* wwpn
*/
if (compare_ether_addr(fip->get_src_addr(vn_port),
vp->fd_mac) != 0 ||
if (!ether_addr_equal(fip->get_src_addr(vn_port),
vp->fd_mac) ||
get_unaligned_be64(&vp->fd_wwpn) !=
vn_port->wwpn)
continue;
......@@ -1453,6 +1492,9 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip,
*/
void fcoe_ctlr_recv(struct fcoe_ctlr *fip, struct sk_buff *skb)
{
skb = skb_share_check(skb, GFP_ATOMIC);
if (!skb)
return;
skb_queue_tail(&fip->fip_recv_list, skb);
schedule_work(&fip->recv_work);
}
......@@ -1479,12 +1521,12 @@ static int fcoe_ctlr_recv_handler(struct fcoe_ctlr *fip, struct sk_buff *skb)
goto drop;
eh = eth_hdr(skb);
if (fip->mode == FIP_MODE_VN2VN) {
if (compare_ether_addr(eh->h_dest, fip->ctl_src_addr) &&
compare_ether_addr(eh->h_dest, fcoe_all_vn2vn) &&
compare_ether_addr(eh->h_dest, fcoe_all_p2p))
if (!ether_addr_equal(eh->h_dest, fip->ctl_src_addr) &&
!ether_addr_equal(eh->h_dest, fcoe_all_vn2vn) &&
!ether_addr_equal(eh->h_dest, fcoe_all_p2p))
goto drop;
} else if (compare_ether_addr(eh->h_dest, fip->ctl_src_addr) &&
compare_ether_addr(eh->h_dest, fcoe_all_enode))
} else if (!ether_addr_equal(eh->h_dest, fip->ctl_src_addr) &&
!ether_addr_equal(eh->h_dest, fcoe_all_enode))
goto drop;
fiph = (struct fip_header *)skb->data;
op = ntohs(fiph->fip_op);
......@@ -1856,7 +1898,7 @@ int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_lport *lport,
* address_mode flag to use FC_OUI-based Ethernet DA.
* Otherwise we use the FCoE gateway addr
*/
if (!compare_ether_addr(sa, (u8[6])FC_FCOE_FLOGI_MAC)) {
if (ether_addr_equal(sa, (u8[6])FC_FCOE_FLOGI_MAC)) {
fcoe_ctlr_map_dest(fip);
} else {
memcpy(fip->dest_addr, sa, ETH_ALEN);
......@@ -2825,8 +2867,8 @@ static void fcoe_ctlr_vn_timeout(struct fcoe_ctlr *fip)
* disabled, so that should ensure that this routine is only called
* when nothing is happening.
*/
void fcoe_ctlr_mode_set(struct fc_lport *lport, struct fcoe_ctlr *fip,
enum fip_state fip_mode)
static void fcoe_ctlr_mode_set(struct fc_lport *lport, struct fcoe_ctlr *fip,
enum fip_state fip_mode)
{
void *priv;
......
......@@ -300,29 +300,29 @@ static ssize_t store_ctlr_mode(struct device *dev,
switch (ctlr->enabled) {
case FCOE_CTLR_ENABLED:
LIBFCOE_SYSFS_DBG(ctlr, "Cannot change mode when enabled.");
LIBFCOE_SYSFS_DBG(ctlr, "Cannot change mode when enabled.\n");
return -EBUSY;
case FCOE_CTLR_DISABLED:
if (!ctlr->f->set_fcoe_ctlr_mode) {
LIBFCOE_SYSFS_DBG(ctlr,
"Mode change not supported by LLD.");
"Mode change not supported by LLD.\n");
return -ENOTSUPP;
}
ctlr->mode = fcoe_parse_mode(mode);
if (ctlr->mode == FIP_CONN_TYPE_UNKNOWN) {
LIBFCOE_SYSFS_DBG(ctlr,
"Unknown mode %s provided.", buf);
LIBFCOE_SYSFS_DBG(ctlr, "Unknown mode %s provided.\n",
buf);
return -EINVAL;
}
ctlr->f->set_fcoe_ctlr_mode(ctlr);
LIBFCOE_SYSFS_DBG(ctlr, "Mode changed to %s.", buf);
LIBFCOE_SYSFS_DBG(ctlr, "Mode changed to %s.\n", buf);
return count;
case FCOE_CTLR_UNUSED:
default:
LIBFCOE_SYSFS_DBG(ctlr, "Mode change not supported.");
LIBFCOE_SYSFS_DBG(ctlr, "Mode change not supported.\n");
return -ENOTSUPP;
};
}
......@@ -653,7 +653,7 @@ static int fcoe_fcf_device_match(struct fcoe_fcf_device *new,
if (new->switch_name == old->switch_name &&
new->fabric_name == old->fabric_name &&
new->fc_map == old->fc_map &&
compare_ether_addr(new->mac, old->mac) == 0)
ether_addr_equal(new->mac, old->mac))
return 1;
return 0;
}
......
......@@ -658,13 +658,13 @@ void fnic_update_mac_locked(struct fnic *fnic, u8 *new)
if (is_zero_ether_addr(new))
new = ctl;
if (!compare_ether_addr(data, new))
if (ether_addr_equal(data, new))
return;
FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "update_mac %pM\n", new);
if (!is_zero_ether_addr(data) && compare_ether_addr(data, ctl))
if (!is_zero_ether_addr(data) && !ether_addr_equal(data, ctl))
vnic_dev_del_addr(fnic->vdev, data);
memcpy(data, new, ETH_ALEN);
if (compare_ether_addr(new, ctl))
if (!ether_addr_equal(new, ctl))
vnic_dev_add_addr(fnic->vdev, new);
}
......
This diff is collapsed.
......@@ -902,7 +902,8 @@ static void fc_fcp_resp(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
/*
* Check for missing or extra data frames.
*/
if (unlikely(fsp->xfer_len != expected_len)) {
if (unlikely(fsp->cdb_status == SAM_STAT_GOOD &&
fsp->xfer_len != expected_len)) {
if (fsp->xfer_len < expected_len) {
/*
* Some data may be queued locally,
......@@ -955,12 +956,11 @@ static void fc_fcp_complete_locked(struct fc_fcp_pkt *fsp)
* Test for transport underrun, independent of response
* underrun status.
*/
if (fsp->xfer_len < fsp->data_len && !fsp->io_status &&
if (fsp->cdb_status == SAM_STAT_GOOD &&
fsp->xfer_len < fsp->data_len && !fsp->io_status &&
(!(fsp->scsi_comp_flags & FCP_RESID_UNDER) ||
fsp->xfer_len < fsp->data_len - fsp->scsi_resid)) {
fsp->xfer_len < fsp->data_len - fsp->scsi_resid))
fsp->status_code = FC_DATA_UNDRUN;
fsp->io_status = 0;
}
}
seq = fsp->seq_ptr;
......
......@@ -516,7 +516,7 @@ static void fc_lport_recv_rnid_req(struct fc_lport *lport,
* @lport: The local port receiving the LOGO
* @fp: The LOGO request frame
*
* Locking Note: The lport lock is exected to be held before calling
* Locking Note: The lport lock is expected to be held before calling
* this function.
*/
static void fc_lport_recv_logo_req(struct fc_lport *lport, struct fc_frame *fp)
......@@ -1088,7 +1088,7 @@ static void fc_lport_error(struct fc_lport *lport, struct fc_frame *fp)
{
unsigned long delay = 0;
FC_LPORT_DBG(lport, "Error %ld in state %s, retries %d\n",
PTR_ERR(fp), fc_lport_state(lport),
IS_ERR(fp) ? -PTR_ERR(fp) : 0, fc_lport_state(lport),
lport->retry_count);
if (PTR_ERR(fp) == -FC_EX_CLOSED)
......
......@@ -1705,7 +1705,7 @@ static void fc_rport_recv_plogi_req(struct fc_lport *lport,
* @rdata: The remote port that sent the PRLI request
* @rx_fp: The PRLI request frame
*
* Locking Note: The rport lock is exected to be held before calling
* Locking Note: The rport lock is expected to be held before calling
* this function.
*/
static void fc_rport_recv_prli_req(struct fc_rport_priv *rdata,
......@@ -1824,7 +1824,7 @@ static void fc_rport_recv_prli_req(struct fc_rport_priv *rdata,
* @rdata: The remote port that sent the PRLO request
* @rx_fp: The PRLO request frame
*
* Locking Note: The rport lock is exected to be held before calling
* Locking Note: The rport lock is expected to be held before calling
* this function.
*/
static void fc_rport_recv_prlo_req(struct fc_rport_priv *rdata,
......@@ -1895,7 +1895,7 @@ static void fc_rport_recv_prlo_req(struct fc_rport_priv *rdata,
* @lport: The local port that received the LOGO request
* @fp: The LOGO request frame
*
* Locking Note: The rport lock is exected to be held before calling
* Locking Note: The rport lock is expected to be held before calling
* this function.
*/
static void fc_rport_recv_logo_req(struct fc_lport *lport, struct fc_frame *fp)
......
......@@ -104,7 +104,7 @@ struct fc_esb {
* esb_e_stat - flags from FC-FS-2 T11/1619-D Rev 0.90.
*/
#define ESB_ST_RESP (1 << 31) /* responder to exchange */
#define ESB_ST_SEQ_INIT (1 << 30) /* port holds sequence initiaive */
#define ESB_ST_SEQ_INIT (1 << 30) /* port holds sequence initiative */
#define ESB_ST_COMPLETE (1 << 29) /* exchange is complete */
#define ESB_ST_ABNORMAL (1 << 28) /* abnormal ending condition */
#define ESB_ST_REC_QUAL (1 << 26) /* recovery qualifier active */
......
......@@ -410,6 +410,12 @@ struct fc_seq {
* @fh_type: The frame type
* @class: The class of service
* @seq: The sequence in use on this exchange
* @resp_active: Number of tasks that are concurrently executing @resp().
* @resp_task: If @resp_active > 0, either the task executing @resp(), the
* task that has been interrupted to execute the soft-IRQ
* executing @resp() or NULL if more than one task is executing
* @resp concurrently.
* @resp_wq: Waitqueue for the tasks waiting on @resp_active.
* @resp: Callback for responses on this exchange
* @destructor: Called when destroying the exchange
* @arg: Passed as a void pointer to the resp() callback
......@@ -441,6 +447,9 @@ struct fc_exch {
u32 r_a_tov;
u32 f_ctl;
struct fc_seq seq;
int resp_active;
struct task_struct *resp_task;
wait_queue_head_t resp_wq;
void (*resp)(struct fc_seq *, struct fc_frame *, void *);
void *arg;
void (*destructor)(struct fc_seq *, void *);
......
......@@ -90,6 +90,7 @@ enum fip_state {
* @lp: &fc_lport: libfc local port.
* @sel_fcf: currently selected FCF, or NULL.
* @fcfs: list of discovered FCFs.
* @cdev: (Optional) pointer to sysfs fcoe_ctlr_device.
* @fcf_count: number of discovered FCF entries.
* @sol_time: time when a multicast solicitation was last sent.
* @sel_time: time after which to select an FCF.
......@@ -127,6 +128,7 @@ struct fcoe_ctlr {
struct fc_lport *lp;
struct fcoe_fcf *sel_fcf;
struct list_head fcfs;
struct fcoe_ctlr_device *cdev;
u16 fcf_count;
unsigned long sol_time;
unsigned long sel_time;
......@@ -168,8 +170,11 @@ static inline void *fcoe_ctlr_priv(const struct fcoe_ctlr *ctlr)
return (void *)(ctlr + 1);
}
/*
* This assumes that the fcoe_ctlr (x) is allocated with the fcoe_ctlr_device.
*/
#define fcoe_ctlr_to_ctlr_dev(x) \
(struct fcoe_ctlr_device *)(((struct fcoe_ctlr_device *)(x)) - 1)
(x)->cdev
/**
* struct fcoe_fcf - Fibre-Channel Forwarder
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment