drivers/scsi/fnic/fnic_fcs.c

Source file repositories/reference/linux-study-clean/drivers/scsi/fnic/fnic_fcs.c

File Facts

System
Linux kernel
Corpus path
drivers/scsi/fnic/fnic_fcs.c
Extension
.c
Size
35355 bytes
Lines
1181
Domain
Driver Families
Bucket
drivers/scsi
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (iport->usefip) {
			iport->state = FNIC_IPORT_STATE_FIP;
			FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
						 "link up: %d, usefip: %d", linkup, iport->usefip);
			fnic_fcoe_send_vlan_req(fnic);
		} else {
			iport->state = FNIC_IPORT_STATE_FABRIC_DISC;
			FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
						 "iport->state: %d", iport->state);
			fnic_fdls_disc_start(iport);
		}
	} else {
		iport->state = FNIC_IPORT_STATE_LINK_WAIT;
		if (!is_zero_ether_addr(iport->fpma))
			vnic_dev_del_addr(fnic->vdev, iport->fpma);
		fnic_common_fip_cleanup(fnic);
		fnic_fdls_link_down(iport);

	}
	spin_unlock_irqrestore(&fnic->fnic_lock, fnic->lock_flags);
}


/*
 * FPMA can be either taken from ethhdr(dst_mac) or flogi resp
 * or derive from FC_MAP and FCID combination. While it should be
 * same, revisit this if there is any possibility of not-correct.
 */
void fnic_fdls_learn_fcoe_macs(struct fnic_iport_s *iport, void *rx_frame,
							   uint8_t *fcid)
{
	struct fnic *fnic = iport->fnic;
	struct ethhdr *ethhdr = (struct ethhdr *) rx_frame;
	uint8_t fcmac[6] = { 0x0E, 0xFC, 0x00, 0x00, 0x00, 0x00 };

	memcpy(&fcmac[3], fcid, 3);

	FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
				 "learn fcoe: dst_mac: %02x:%02x:%02x:%02x:%02x:%02x",
				 ethhdr->h_dest[0], ethhdr->h_dest[1],
				 ethhdr->h_dest[2], ethhdr->h_dest[3],
				 ethhdr->h_dest[4], ethhdr->h_dest[5]);

	FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
				 "learn fcoe: fc_mac: %02x:%02x:%02x:%02x:%02x:%02x",
				 fcmac[0], fcmac[1], fcmac[2], fcmac[3], fcmac[4],
				 fcmac[5]);

	fnic_fdls_set_fcoe_srcmac(fnic, fcmac);
	fnic_fdls_set_fcoe_dstmac(fnic, ethhdr->h_source);
}

void fnic_fdls_init(struct fnic *fnic, int usefip)
{
	struct fnic_iport_s *iport = &fnic->iport;

	/* Initialize iPort structure */
	iport->state = FNIC_IPORT_STATE_INIT;
	iport->fnic = fnic;
	iport->usefip = usefip;

	FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
				 "iportsrcmac: %02x:%02x:%02x:%02x:%02x:%02x",
				 iport->hwmac[0], iport->hwmac[1], iport->hwmac[2],
				 iport->hwmac[3], iport->hwmac[4], iport->hwmac[5]);

	INIT_LIST_HEAD(&iport->tport_list);
	INIT_LIST_HEAD(&iport->tport_list_pending_del);

	fnic_fdls_disc_init(iport);
}

void fnic_handle_link(struct work_struct *work)
{
	struct fnic *fnic = container_of(work, struct fnic, link_work);
	int old_link_status;
	u32 old_link_down_cnt;
	int max_count = 0;

	if (vnic_dev_get_intr_mode(fnic->vdev) != VNIC_DEV_INTR_MODE_MSI)
		FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
					 "Interrupt mode is not MSI\n");

	spin_lock_irqsave(&fnic->fnic_lock, fnic->lock_flags);

	if (fnic->stop_rx_link_events) {
		spin_unlock_irqrestore(&fnic->fnic_lock, fnic->lock_flags);
		FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num,
					 "Stop link rx events\n");
		return;

Annotation

Implementation Notes