Exemplo n.º 1
0
static void
bfa_msgq_cmdq_ci_update(struct bfa_msgq_cmdq *cmdq, struct bfi_mbmsg *mb)
{
	struct bfi_msgq_i2h_db *dbell = (struct bfi_msgq_i2h_db *)mb;
	struct bfa_msgq_cmd_entry *cmd;
	int posted = 0;

	cmdq->consumer_index = ntohs(dbell->idx.cmdq_ci);

	/* Walk through pending list to see if the command can be posted */
	while (!list_empty(&cmdq->pending_q)) {
		cmd =
		(struct bfa_msgq_cmd_entry *)bfa_q_first(&cmdq->pending_q);
		if (ntohs(cmd->msg_hdr->num_entries) <=
			BFA_MSGQ_FREE_CNT(cmdq)) {
			list_del(&cmd->qe);
			__cmd_copy(cmdq, cmd);
			posted = 1;
			call_cmdq_ent_cbfn(cmd, BFA_STATUS_OK);
		} else {
			break;
		}
	}

	if (posted)
		bfa_fsm_send_event(cmdq, CMDQ_E_POST);
}
Exemplo n.º 2
0
void
bfa_sgpg_mfree(struct bfa_s *bfa, struct list_head *sgpg_q, int nsgpg)
{
	struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa);
	struct bfa_sgpg_wqe_s *wqe;

	bfa_trc_fp(bfa, nsgpg);

	mod->free_sgpgs += nsgpg;
	bfa_assert(mod->free_sgpgs <= mod->num_sgpgs);

	bfa_q_enq_q(&mod->sgpg_q, sgpg_q);

	if (list_empty(&mod->sgpg_wait_q))
		return;

	/**
	 * satisfy as many waiting requests as possible
	 */
	do {
		wqe = bfa_q_first(&mod->sgpg_wait_q);
		if (mod->free_sgpgs < wqe->nsgpg)
			nsgpg = mod->free_sgpgs;
		else
			nsgpg = wqe->nsgpg;
		bfa_sgpg_malloc(bfa, &wqe->sgpg_q, nsgpg);
		wqe->nsgpg -= nsgpg;
		if (wqe->nsgpg == 0) {
			list_del(&wqe->qe);
			wqe->cbfn(wqe->cbarg);
		}
	} while (mod->free_sgpgs && !list_empty(&mod->sgpg_wait_q));
}
Exemplo n.º 3
0
static void
bfa_ioim_sgpg_setup(struct bfa_ioim_s *ioim)
{
	int             sgeid, nsges, i;
	struct bfi_sge_s      *sge;
	struct bfa_sgpg_s *sgpg;
	u32        pgcumsz;
	u64        addr;
	struct scatterlist *sg;
	struct scsi_cmnd *cmnd = (struct scsi_cmnd *) ioim->dio;

	sgeid = BFI_SGE_INLINE;
	ioim->sgpg = sgpg = bfa_q_first(&ioim->sgpg_q);

	sg = scsi_sglist(cmnd);
	sg = sg_next(sg);

	do {
		sge = sgpg->sgpg->sges;
		nsges = ioim->nsges - sgeid;
		if (nsges > BFI_SGPG_DATA_SGES)
			nsges = BFI_SGPG_DATA_SGES;

		pgcumsz = 0;
		for (i = 0; i < nsges; i++, sge++, sgeid++, sg = sg_next(sg)) {
			addr = bfa_os_sgaddr(sg_dma_address(sg));
			sge->sga = *(union bfi_addr_u *) &addr;
			sge->sg_len = sg_dma_len(sg);
			pgcumsz += sge->sg_len;

			/**
			 * set flags
			 */
			if (i < (nsges - 1))
				sge->flags = BFI_SGE_DATA;
			else if (sgeid < (ioim->nsges - 1))
				sge->flags = BFI_SGE_DATA_CPL;
			else
				sge->flags = BFI_SGE_DATA_LAST;
		}

		sgpg = (struct bfa_sgpg_s *) bfa_q_next(sgpg);

		/**
		 * set the link element of each page
		 */
		if (sgeid == ioim->nsges) {
			sge->flags = BFI_SGE_PGDLEN;
			sge->sga.a32.addr_lo = 0;
			sge->sga.a32.addr_hi = 0;
		} else {
			sge->flags = BFI_SGE_LINK;
			sge->sga = sgpg->sgpg_pa;
		}
		sge->sg_len = pgcumsz;
	} while (sgeid < ioim->nsges);
}
Exemplo n.º 4
0
/*
 * Iterate's through all the rport's in the given port to
 * determine the maximum operating speed.
 *
 * To be used in TRL Functionality only
 */
enum bfa_pport_speed
bfa_fcs_port_get_rport_max_speed(struct bfa_fcs_port_s *port)
{
	struct list_head *qh, *qe;
	struct bfa_fcs_rport_s *rport = NULL;
	struct bfa_fcs_s *fcs;
	enum bfa_pport_speed max_speed = 0;
	struct bfa_pport_attr_s pport_attr;
	enum bfa_pport_speed pport_speed, rport_speed;
	bfa_boolean_t     trl_enabled = bfa_fcport_is_ratelim(port->fcs->bfa);

	if (port == NULL)
		return 0;

	fcs = port->fcs;

	/*
	 * Get Physical port's current speed
	 */
	bfa_fcport_get_attr(port->fcs->bfa, &pport_attr);
	pport_speed = pport_attr.speed;
	bfa_trc(fcs, pport_speed);

	qh = &port->rport_q;
	qe = bfa_q_first(qh);

	while (qe != qh) {
		rport = (struct bfa_fcs_rport_s *) qe;
		if ((bfa_os_ntoh3b(rport->pid) > 0xFFF000) ||
			(bfa_fcs_rport_get_state(rport) ==
						BFA_RPORT_OFFLINE)) {
			qe = bfa_q_next(qe);
			continue;
		}

		rport_speed = rport->rpf.rpsc_speed;
		if ((trl_enabled) &&  (rport_speed ==
						BFA_PPORT_SPEED_UNKNOWN)) {
			/* Use default ratelim speed setting */
			rport_speed =
				bfa_fcport_get_ratelim_speed(port->fcs->bfa);
		}

		if ((rport_speed  == BFA_PPORT_SPEED_8GBPS) ||
			(rport_speed > pport_speed)) {
			max_speed = rport_speed;
			break;
		} else if (rport_speed > max_speed) {
			max_speed = rport_speed;
		}

		qe = bfa_q_next(qe);
	}

	bfa_trc(fcs, max_speed);
	return max_speed;
}
Exemplo n.º 5
0
static void
bfa_ioim_sgpg_setup(struct bfa_ioim_s *ioim)
{
	int             sgeid, nsges, i;
	struct bfi_sge_s      *sge;
	struct bfa_sgpg_s *sgpg;
	u32        pgcumsz;

	sgeid = BFI_SGE_INLINE;
	ioim->sgpg = sgpg = bfa_q_first(&ioim->sgpg_q);

	do {
		sge = sgpg->sgpg->sges;
		nsges = ioim->nsges - sgeid;
		if (nsges > BFI_SGPG_DATA_SGES)
			nsges = BFI_SGPG_DATA_SGES;

		pgcumsz = 0;
		for (i = 0; i < nsges; i++, sge++, sgeid++) {
			sge->sga = bfa_cb_ioim_get_sgaddr(ioim->dio, sgeid);
			sge->sg_len = bfa_cb_ioim_get_sglen(ioim->dio, sgeid);
			pgcumsz += sge->sg_len;

			/**
			 * set flags
			 */
			if (i < (nsges - 1))
				sge->flags = BFI_SGE_DATA;
			else if (sgeid < (ioim->nsges - 1))
				sge->flags = BFI_SGE_DATA_CPL;
			else
				sge->flags = BFI_SGE_DATA_LAST;
		}

		sgpg = (struct bfa_sgpg_s *) bfa_q_next(sgpg);

		/**
		 * set the link element of each page
		 */
		if (sgeid == ioim->nsges) {
			sge->flags = BFI_SGE_PGDLEN;
			sge->sga.a32.addr_lo = 0;
			sge->sga.a32.addr_hi = 0;
		} else {
			sge->flags = BFI_SGE_LINK;
			sge->sga = sgpg->sgpg_pa;
		}
		sge->sg_len = pgcumsz;
	} while (sgeid < ioim->nsges);
}
Exemplo n.º 6
0
wwn_t
bfa_fcs_port_get_rport(struct bfa_fcs_port_s *port, wwn_t wwn, int index,
		       int nrports, bfa_boolean_t bwwn)
{
	struct list_head *qh, *qe;
	struct bfa_fcs_rport_s *rport = NULL;
	int             i;
	struct bfa_fcs_s *fcs;

	if (port == NULL || nrports == 0)
		return (wwn_t) 0;

	fcs = port->fcs;
	bfa_trc(fcs, (u32) nrports);

	i = 0;
	qh = &port->rport_q;
	qe = bfa_q_first(qh);

	while ((qe != qh) && (i < nrports)) {
		rport = (struct bfa_fcs_rport_s *)qe;
		if (bfa_os_ntoh3b(rport->pid) > 0xFFF000) {
			qe = bfa_q_next(qe);
			bfa_trc(fcs, (u32) rport->pwwn);
			bfa_trc(fcs, rport->pid);
			bfa_trc(fcs, i);
			continue;
		}

		if (bwwn) {
			if (!memcmp(&wwn, &rport->pwwn, 8))
				break;
		} else {
			if (i == index)
				break;
		}

		i++;
		qe = bfa_q_next(qe);
	}

	bfa_trc(fcs, i);
	if (rport)
		return rport->pwwn;
	else
		return (wwn_t) 0;
}
Exemplo n.º 7
0
void
bfa_fcs_port_get_rports(struct bfa_fcs_port_s *port, wwn_t rport_wwns[],
			int *nrports)
{
	struct list_head *qh, *qe;
	struct bfa_fcs_rport_s *rport = NULL;
	int             i;
	struct bfa_fcs_s *fcs;

	if (port == NULL || rport_wwns == NULL || *nrports == 0)
		return;

	fcs = port->fcs;
	bfa_trc(fcs, (u32) *nrports);

	i = 0;
	qh = &port->rport_q;
	qe = bfa_q_first(qh);

	while ((qe != qh) && (i < *nrports)) {
		rport = (struct bfa_fcs_rport_s *)qe;
		if (bfa_os_ntoh3b(rport->pid) > 0xFFF000) {
			qe = bfa_q_next(qe);
			bfa_trc(fcs, (u32) rport->pwwn);
			bfa_trc(fcs, rport->pid);
			bfa_trc(fcs, i);
			continue;
		}

		rport_wwns[i] = rport->pwwn;

		i++;
		qe = bfa_q_next(qe);
	}

	bfa_trc(fcs, i);
	*nrports = i;
	return;
}