Beispiel #1
0
/*
 * Description: This function is called when user disables EMF on a bridge
 *              interface. It unregisters the Netfilter hook functions,
 *              calls the common code cleanup routine and releases all the
 *              resources allocated during instance creation.
 *
 * Input:       emf      - EMF module global data pointer
 *              emf_info - EMF instance data pointer
 */
static int32
emf_instance_del(emf_struct_t *emf, emf_info_t *emfi)
{
	bool found = FALSE;
	osl_t *osh;
	emf_info_t *ptr, *prev;
#ifdef CONFIG_PROC_FS
	uint8 proc_name[64];
#endif /* CONFIG_PROC_FS */

	/* Interfaces attached to the EMF instance should be deleted first */
	emf_iflist_clear(emf, emfi);

	/* Delete the EMF instance */
	prev = NULL;
	for (ptr = emf->list_head; ptr != NULL; prev = ptr, ptr = ptr->next)
	{
		if (ptr == emfi)
		{
			found = TRUE;
			if (prev != NULL)
				prev->next = ptr->next;
			else
				emf->list_head = NULL;
			break;
		}
	}

	if (!found)
	{
		EMF_ERROR("EMF instance not found\n");
		return (FAILURE);
	}

	emf->inst_count--;

	/* Free the EMF instance */
	OSL_UNLOCK(emf->lock);
	emf_hooks_unregister(ptr);
	OSL_LOCK(emf->lock);
	emfc_exit(ptr->emfci);

#ifdef CONFIG_PROC_FS
	sprintf(proc_name, "net/emf_stats_%s", emfi->inst_id);
	remove_proc_entry(proc_name, 0);
	sprintf(proc_name, "net/emfdb_%s", emfi->inst_id);
	remove_proc_entry(proc_name, 0);
#endif /* CONFIG_PROC_FS */

	osh = ptr->osh;
	MFREE(emfi->osh, ptr, sizeof(emf_info_t));
	osl_detach(osh);

	return (SUCCESS);
}
Beispiel #2
0
static int32
igs_instance_del(igs_info_t *igs_info)
{
	bool found = FALSE;
	osl_t *osh;
	igs_info_t *ptr, *prev;
	uint8 proc_name[64];

	OSL_LOCK(igs.lock);

	/* Delete the IGS instance */
	prev = NULL;
	for (ptr = igs.list_head; ptr != NULL; prev = ptr, ptr = ptr->next)
	{
		if (ptr == igs_info)
		{
			found = TRUE;
			if (prev != NULL)
				prev->next = ptr->next;
			else
				igs.list_head = igs.list_head->next;
			break;
		}
	}

	OSL_UNLOCK(igs.lock);

	if (!found)
	{
		IGS_ERROR("IGS instance not found\n");
		return (FAILURE);
	}

	igs.inst_count--;

	/* Free the IGS instance */
	igsc_exit(igs_info->igsc_info);

#ifdef CONFIG_PROC_FS
	sprintf(proc_name, "emf/igs_stats_%s", igs_info->inst_id);
	remove_proc_entry(proc_name, 0);
	sprintf(proc_name, "emf/igsdb_%s", igs_info->inst_id);
	remove_proc_entry(proc_name, 0);
#endif /* CONFIG_PROC_FS */

	osh = igs_info->osh;
	MFREE(igs_info->osh, igs_info, sizeof(igs_info_t));
	osl_detach(osh);

	return (SUCCESS);
}
static void sdioh_remove(struct sdio_func *func)
{
	sdioh_info_t *sdioh;
	osl_t *osh;

	sdioh = sdio_get_drvdata(func);
	if (sdioh == NULL) {
		sd_err(("%s: error, no sdioh handler found\n", __FUNCTION__));
		return;
	}

	osh = sdioh->osh;
	bcmsdh_remove(sdioh->bcmsdh);
	sdioh_detach(osh, sdioh);
	osl_detach(osh);
}
static int sdioh_probe(struct sdio_func *func)
{
	int host_idx = func->card->host->index;
	uint32 rca = func->card->rca;
	wifi_adapter_info_t *adapter;
	osl_t *osh = NULL;
	sdioh_info_t *sdioh = NULL;

	sd_err(("bus num (host idx)=%d, slot num (rca)=%d\n", host_idx, rca));
	adapter = dhd_wifi_platform_get_adapter(SDIO_BUS, host_idx, rca);
	if (adapter  != NULL)
		sd_err(("found adapter info '%s'\n", adapter->name));
	else
		sd_err(("can't find adapter info for this chip\n"));

#ifdef WL_CFG80211
	wl_cfg80211_set_parent_dev(&func->dev);
#endif

	 /* allocate SDIO Host Controller state info */
	 osh = osl_attach(&func->dev, SDIO_BUS, TRUE);
	 if (osh == NULL) {
		 sd_err(("%s: osl_attach failed\n", __FUNCTION__));
		 goto fail;
	 }
	 osl_static_mem_init(osh, adapter);
	 sdioh = sdioh_attach(osh, func);
	 if (sdioh == NULL) {
		 sd_err(("%s: sdioh_attach failed\n", __FUNCTION__));
		 goto fail;
	 }
	 sdioh->bcmsdh = bcmsdh_probe(osh, &func->dev, sdioh, adapter, SDIO_BUS, host_idx, rca);
	 if (sdioh->bcmsdh == NULL) {
		 sd_err(("%s: bcmsdh_probe failed\n", __FUNCTION__));
		 goto fail;
	 }

	sdio_set_drvdata(func, sdioh);
	return 0;

fail:
	if (sdioh != NULL)
		sdioh_detach(osh, sdioh);
	if (osh != NULL)
		osl_detach(osh);
	return -ENOMEM;
}
Beispiel #5
0
static
#endif				/* BCMLXSDMMC */
int bcmsdh_remove(struct device *dev)
{
	bcmsdh_hc_t *sdhc, *prev;
	struct osl_info *osh;

	sdhc = sdhcinfo;
	drvinfo.detach(sdhc->ch);
	bcmsdh_detach(sdhc->osh, sdhc->sdh);
	/* find the SDIO Host Controller state for this pdev
		 and take it out from the list */
	for (sdhc = sdhcinfo, prev = NULL; sdhc; sdhc = sdhc->next) {
		if (sdhc->dev == (void *)dev) {
			if (prev)
				prev->next = sdhc->next;
			else
				sdhcinfo = NULL;
			break;
		}
		prev = sdhc;
	}
	if (!sdhc) {
		SDLX_MSG(("%s: failed\n", __func__));
		return 0;
	}

	/* release SDIO Host Controller info */
	osh = sdhc->osh;
	kfree(sdhc);
	osl_detach(osh);

#if !defined(BCMLXSDMMC)
	dev_set_drvdata(dev, NULL);
#endif				/* !defined(BCMLXSDMMC) */

	return 0;
}
Beispiel #6
0
/*
 * Description: This function is called when the user application enables
 *              EMF on a bridge interface. It primarily allocates memory
 *              for instance data and calls the common code init function.
 *
 * Input:       emf     - EMF module global data pointer
 *              inst_id - EMF instance name
 *              br_ptr  - Bridge device pointer
 */
static emf_info_t *
emf_instance_add(emf_struct_t *emf, int8 *inst_id, struct net_device *br_ptr)
{
	emf_info_t *emfi;
	osl_t *osh;
#ifdef CONFIG_PROC_FS
	uint8 proc_name[64];
#endif /* CONFIG_PROC_FS */
	emfc_wrapper_t emfl;

	if (emf->inst_count > EMF_MAX_INST)
	{
		EMF_ERROR("Max instance limit %d exceeded\n", EMF_MAX_INST);
		return (NULL);
	}

	emf->inst_count++;

	EMF_INFO("Creating EMF instance for %s\n", inst_id);

	osh = osl_attach(NULL, PCI_BUS, FALSE);

	ASSERT(osh);

	/* Allocate os specfic EMF info object */
	emfi = MALLOC(osh, sizeof(emf_info_t));
	if (emfi == NULL)
	{
		EMF_ERROR("Out of memory allocating emf_info\n");
		osl_detach(osh);
		return (NULL);
	}

	emfi->osh = osh;

	/* Save the EMF instance identifier */
	strncpy(emfi->inst_id, inst_id, IFNAMSIZ);
	emfi->inst_id[IFNAMSIZ - 1] = 0;

	/* Save the device pointer */
	emfi->br_dev = br_ptr;

	/* Fill the linux wrapper specific functions */
	emfl.forward_fn = (forward_fn_ptr)emf_forward;
	emfl.sendup_fn = (sendup_fn_ptr)emf_sendup;
	emfl.hooks_register_fn = (hooks_register_fn_ptr)emf_hooks_register;
	emfl.hooks_unregister_fn = (hooks_unregister_fn_ptr)emf_hooks_unregister;

	/* Initialize EMFC instance */
	if ((emfi->emfci = emfc_init(inst_id, (void *)emfi, osh, &emfl)) == NULL)
	{
		EMF_ERROR("EMFC init failed\n");
		MFREE(osh, emfi, sizeof(emf_info_t));
		osl_detach(osh);
		return (NULL);
	}

	EMF_INFO("Created EMFC instance for %s\n", inst_id);

	/* Initialize the iflist head */
	emfi->iflist_head = NULL;

#ifdef CONFIG_PROC_FS
	sprintf(proc_name, "net/emf_stats_%s", inst_id);
	create_proc_read_entry(proc_name, 0, 0, emf_stats_get, emfi);
	sprintf(proc_name, "net/emfdb_%s", inst_id);
	create_proc_read_entry(proc_name, 0, 0, emf_mfdb_list, emfi);
#endif /* CONFIG_PROC_FS */

	/* Add to the global EMF instance list */
	emfi->next = emf->list_head;
	emf->list_head = emfi;

	return (emfi);
}
Beispiel #7
0
/*
 * Description: This function is called when user application enables snooping
 *              on a bridge interface. It primarily allocates memory for IGS
 *              instance data and calls common code initialization function.
 */
static igs_info_t *
igs_instance_add(int8 *inst_id, struct net_device *br_ptr)
{
	igs_info_t *igs_info;
	osl_t *osh;
	uint8 proc_name[64];
	igsc_wrapper_t igsl;

	if (igs.inst_count > IGS_MAX_INST)
	{
		IGS_ERROR("Max instance limit %d exceeded\n", IGS_MAX_INST);
		return (NULL);
	}

	igs.inst_count++;

	IGS_INFO("Creating IGS instance for %s\n", inst_id);

	osh = osl_attach(NULL, PCI_BUS, FALSE);

	ASSERT(osh);

	/* Allocate os specfic IGS info object */
	igs_info = MALLOC(osh, sizeof(igs_info_t));
	if (igs_info == NULL)
	{
		IGS_ERROR("Out of memory allocating igs_info\n");
		osl_detach(osh);
		return (NULL);
	}

	igs_info->osh = osh;

	/* Save the IGS instance identifier */
	strncpy(igs_info->inst_id, inst_id, IFNAMSIZ);
	igs_info->inst_id[IFNAMSIZ - 1] = 0;

	/* Save the device pointer */
	igs_info->br_dev = br_ptr;

	/* Fill in linux specific wrapper functions*/
	igsl.igs_broadcast = (igs_broadcast_fn_ptr)igs_broadcast;

	/* Initialize IGSC layer */
	if ((igs_info->igsc_info = igsc_init(inst_id, (void *)igs_info, osh, &igsl)) == NULL)
	{
		IGS_ERROR("IGSC init failed\n");
		MFREE(osh, igs_info, sizeof(igs_info_t));
		osl_detach(osh);
		return (NULL);
	}

#ifdef CONFIG_PROC_FS
	sprintf(proc_name, "net/igs_stats_%s", inst_id);
	create_proc_read_entry(proc_name, 0, 0, igs_stats_get, igs_info);
	sprintf(proc_name, "net/igsdb_%s", inst_id);
	create_proc_read_entry(proc_name, 0, 0, igs_sdb_list, igs_info);
#endif /* CONFIG_PROC_FS */

	IGS_INFO("Created IGSC instance for %s\n", inst_id);

	/* Add to global IGS instance list */
	OSL_LOCK(igs.lock);
	igs_info->next = igs.list_head;
	igs.list_head = igs_info;
	OSL_UNLOCK(igs.lock);

	return (igs_info);
}
Beispiel #8
0
static
#endif				/* BCMLXSDMMC */
int bcmsdh_probe(struct device *dev)
{
	struct osl_info *osh = NULL;
	bcmsdh_hc_t *sdhc = NULL;
	unsigned long regs = 0;
	bcmsdh_info_t *sdh = NULL;
#if !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS)
	struct platform_device *pdev;
	struct resource *r;
#endif				/* BCMLXSDMMC */
	int irq = 0;
	u32 vendevid;
	unsigned long irq_flags = 0;

#if !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS)
	pdev = to_platform_device(dev);
	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	irq = platform_get_irq(pdev, 0);
	if (!r || irq == NO_IRQ)
		return -ENXIO;
#endif				/* BCMLXSDMMC */

#if defined(OOB_INTR_ONLY)
#ifdef HW_OOB
	irq_flags =
	    IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL |
	    IORESOURCE_IRQ_SHAREABLE;
#else
	irq_flags = IRQF_TRIGGER_FALLING;
#endif				/* HW_OOB */
	irq = dhd_customer_oob_irq_map(&irq_flags);
	if (irq < 0) {
		SDLX_MSG(("%s: Host irq is not defined\n", __func__));
		return 1;
	}
#endif				/* defined(OOB_INTR_ONLY) */
	/* allocate SDIO Host Controller state info */
	osh = osl_attach(dev, PCI_BUS);
	if (!osh) {
		SDLX_MSG(("%s: osl_attach failed\n", __func__));
		goto err;
	}
	sdhc = kzalloc(sizeof(bcmsdh_hc_t), GFP_ATOMIC);
	if (!sdhc) {
		SDLX_MSG(("%s: out of memory\n", __func__));
		goto err;
	}
	sdhc->osh = osh;

	sdhc->dev = (void *)dev;

#ifdef BCMLXSDMMC
	sdh = bcmsdh_attach(osh, (void *)0, (void **)&regs, irq);
	if (!sdh) {
		SDLX_MSG(("%s: bcmsdh_attach failed\n", __func__));
		goto err;
	}
#else
	sdh = bcmsdh_attach(osh, (void *)r->start, (void **)&regs, irq);
	if (!sdh) {
		SDLX_MSG(("%s: bcmsdh_attach failed\n", __func__));
		goto err;
	}
#endif				/* BCMLXSDMMC */
	sdhc->sdh = sdh;
	sdhc->oob_irq = irq;
	sdhc->oob_flags = irq_flags;
	sdhc->oob_irq_registered = false;	/* to make sure.. */
#if defined(OOB_INTR_ONLY)
	spin_lock_init(&sdhc->irq_lock);
#endif

	/* chain SDIO Host Controller info together */
	sdhc->next = sdhcinfo;
	sdhcinfo = sdhc;
	/* Read the vendor/device ID from the CIS */
	vendevid = bcmsdh_query_device(sdh);

	/* try to attach to the target device */
	sdhc->ch = drvinfo.attach((vendevid >> 16), (vendevid & 0xFFFF),
				0, 0, 0, 0, (void *)regs, NULL, sdh);
	if (!sdhc->ch) {
		SDLX_MSG(("%s: device attach failed\n", __func__));
		goto err;
	}

	return 0;

	/* error handling */
err:
	if (sdhc) {
		if (sdhc->sdh)
			bcmsdh_detach(sdhc->osh, sdhc->sdh);
		kfree(sdhc);
	}
	if (osh)
		osl_detach(osh);
	return -ENODEV;
}