Beispiel #1
0
static int wl_suspend(struct pci_dev *pdev, pm_message_t state)
{
	struct wl_info *wl;
	struct ieee80211_hw *hw;

	WL_TRACE("wl: wl_suspend\n");

	hw = pci_get_drvdata(pdev);
	wl = HW_TO_WL(hw);
	if (!wl) {
		WL_ERROR("wl: wl_suspend: pci_get_drvdata failed\n");
		return -ENODEV;
	}

	/* only need to flag hw is down for proper resume */
	WL_LOCK(wl);
	wl->pub->hw_up = false;
	WL_UNLOCK(wl);

	pci_save_state(pdev);
	pci_disable_device(pdev);
	return pci_set_power_state(pdev, PCI_D3hot);
}
static int wl_resume(struct pci_dev *pdev)
{
	struct wl_info *wl;
	struct ieee80211_hw *hw;
	int err = 0;
	u32 val;

	WL_TRACE("wl: wl_resume\n");
	hw = pci_get_drvdata(pdev);
	wl = HW_TO_WL(hw);
	if (!wl) {
		WL_ERROR("wl: wl_resume: pci_get_drvdata failed\n");
		return -ENODEV;
	}

	err = pci_set_power_state(pdev, PCI_D0);
	if (err)
		return err;

	pci_restore_state(pdev);

	err = pci_enable_device(pdev);
	if (err)
		return err;

	pci_set_master(pdev);

	pci_read_config_dword(pdev, 0x40, &val);
	if ((val & 0x0000ff00) != 0)
		pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);

	/*
	*  done. driver will be put in up state
	*  in wl_ops_add_interface() call.
	*/
	return err;
}
int dhd_customer_oob_irq_map(unsigned long *irq_flags_ptr)
{
	int  host_oob_irq = 0;

#ifdef CUSTOMER_HW2
	host_oob_irq = wifi_get_irq_number(irq_flags_ptr);

#else /* for NOT  CUSTOMER_HW2 */
#if defined(CUSTOM_OOB_GPIO_NUM)
	if (dhd_oob_gpio_num < 0) {
		dhd_oob_gpio_num = CUSTOM_OOB_GPIO_NUM;
	}
#endif

	if (dhd_oob_gpio_num < 0) {
		WL_ERROR(("%s: ERROR customer specific Host GPIO is NOT defined \n",
			__FUNCTION__));
		return (dhd_oob_gpio_num);
	}

	
	

	printk("%s: customer specific Host GPIO number is (%d)\n",
		         __FUNCTION__, dhd_oob_gpio_num);
#if defined CUSTOMER_HW
	host_oob_irq = MSM_GPIO_TO_INT(dhd_oob_gpio_num);
#elif defined CUSTOMER_HW3
	gpio_request(dhd_oob_gpio_num, "oob irq");
	host_oob_irq = gpio_to_irq(dhd_oob_gpio_num);
	gpio_direction_input(dhd_oob_gpio_num);
#endif /* CUSTOMER_HW */
#endif /* CUSTOMER_HW2 */

	return (host_oob_irq);
}
Beispiel #4
0
/*
 * Export functions
 */
wlc_eventq_t *wlc_eventq_attach(wlc_pub_t *pub, struct wlc_info *wlc, void *wl,
				wlc_eventq_cb_t cb)
{
	wlc_eventq_t *eq;

	eq = kzalloc(sizeof(wlc_eventq_t), GFP_ATOMIC);
	if (eq == NULL)
		return NULL;

	eq->cb = cb;
	eq->wlc = wlc;
	eq->wl = wl;
	eq->pub = pub;

	eq->timer = wl_init_timer(eq->wl, wlc_timer_cb, eq, "eventq");
	if (!eq->timer) {
		WL_ERROR(("wl%d: wlc_eventq_attach: timer failed\n",
			  pub->unit));
		kfree(eq);
		return NULL;
	}

	return eq;
}
Beispiel #5
0
/* Lookup a country info structure from a null terminated country
 * abbreviation and regrev directly with no translation.
 */
static const country_info_t *wlc_country_lookup_direct(const char *ccode,
						       uint regrev)
{
	uint size, i;

	/* Should just return 0 for single locale driver. */
	/* Keep it this way in case we add more locales. (for now anyway) */

	/* all other country def arrays are for regrev == 0, so if regrev is non-zero, fail */
	if (regrev > 0)
		return NULL;

	/* find matched table entry from country code */
	size = ARRAY_SIZE(cntry_locales);
	for (i = 0; i < size; i++) {
		if (strcmp(ccode, cntry_locales[i].abbrev) == 0) {
			return &cntry_locales[i].country;
		}
	}

	WL_ERROR("%s: Returning NULL\n", __func__);
	ASSERT(0);
	return NULL;
}
/* Customer function to control hw specific wlan gpios */
void
dhd_customer_gpio_wlan_ctrl(int onoff)
{
#if defined CONFIG_MMC_SUNXI_POWER_CONTROL
    unsigned int mod_sel = mmc_pm_get_mod_type();
    if (mod_sel != 6) {
        printk("Config Error: not for huawei mw269x sdio wifi module\n");
    }
#endif
	switch (onoff) {
		case WLAN_RESET_OFF:
			WL_TRACE(("%s: call customer specific GPIO to insert WLAN RESET\n",
				__FUNCTION__));
#if defined CONFIG_MMC_SUNXI_POWER_CONTROL
            mmc_pm_gpio_ctrl("hw_mw269x_wl_enb", 0);
#endif
#ifdef CUSTOMER_HW
			bcm_wlan_power_off(2);
#endif /* CUSTOMER_HW */
#ifdef CUSTOMER_HW2
			wifi_set_power(0, 0);
#endif
			WL_ERROR(("=========== WLAN placed in RESET ========\n"));
		break;

		case WLAN_RESET_ON:
			WL_TRACE(("%s: callc customer specific GPIO to remove WLAN RESET\n",
				__FUNCTION__));
#if defined CONFIG_MMC_SUNXI_POWER_CONTROL
            mmc_pm_gpio_ctrl("hw_mw269x_wl_enb", 1);
#endif
#ifdef CUSTOMER_HW
			bcm_wlan_power_on(2);
#endif /* CUSTOMER_HW */
#ifdef CUSTOMER_HW2
			wifi_set_power(1, 0);
#endif
			WL_ERROR(("=========== WLAN going back to live  ========\n"));
			OSL_DELAY(10000);
		break;

		case WLAN_POWER_OFF:
			WL_TRACE(("%s: call customer specific GPIO to turn off WL_REG_ON\n",
				__FUNCTION__));
#if defined CONFIG_MMC_SUNXI_POWER_CONTROL
            mmc_pm_gpio_ctrl("hw_mw269x_wl_enb", 0);
            sunximmc_rescan_card(SDIOID, 0);
#endif
#ifdef CUSTOMER_HW
			bcm_wlan_power_off(1);
#endif /* CUSTOMER_HW */
		break;

		case WLAN_POWER_ON:
			WL_TRACE(("%s: call customer specific GPIO to turn on WL_REG_ON\n",
				__FUNCTION__));
#if defined CONFIG_MMC_SUNXI_POWER_CONTROL
            mmc_pm_gpio_ctrl("hw_mw269x_wl_enb", 1);
#endif
#ifdef CUSTOMER_HW
			bcm_wlan_power_on(1);
#endif /* CUSTOMER_HW */
			/* Lets customer power to get stable */
			OSL_DELAY(200);
#if defined CONFIG_MMC_SUNXI_POWER_CONTROL
            sunximmc_rescan_card(SDIOID, 1);
#endif /* CUSTOMER_HW */
		break;
	}
}
/* Customer function to control hw specific wlan gpios */
void
dhd_customer_gpio_wlan_ctrl(int onoff)
{
    static int first = 1;
    static int sdc_id = 1;

    script_item_value_type_e type;
    script_item_u val;

    if (first == 1) {
        type = script_get_item("wifi_para", "wifi_sdc_id", &val);
        if (SCIRPT_ITEM_VALUE_TYPE_INT != type) {
            WL_ERROR(("failed to fetch sdio card's sdcid\n"));
            return -1;
        }
        sdc_id = val.val;
        first = 0;
    }

    switch (onoff) {
    case WLAN_RESET_OFF:
        WL_TRACE(("%s: call customer specific GPIO to insert WLAN RESET\n",
                  __FUNCTION__));
#ifdef CUSTOMER_HW
        wifi_pm_power(0);
#endif /* CUSTOMER_HW */
#if defined(CUSTOMER_HW2)
        wifi_set_power(0, 0);
#endif
        mdelay(100);
        WL_ERROR(("=========== WLAN placed in RESET ========\n"));
        break;

    case WLAN_RESET_ON:
        WL_TRACE(("%s: callc customer specific GPIO to remove WLAN RESET\n",
                  __FUNCTION__));
#ifdef CUSTOMER_HW
        wifi_pm_power(1);
#endif /* CUSTOMER_HW */
#if defined(CUSTOMER_HW2)
        wifi_set_power(1, 0);
#endif
        mdelay(100);
        WL_ERROR(("=========== WLAN going back to live  ========\n"));
        break;

    case WLAN_POWER_OFF:
        WL_TRACE(("%s: call customer specific GPIO to turn off WL_REG_ON\n",
                  __FUNCTION__));
#ifdef CUSTOMER_HW
        wifi_pm_power(0);
        sw_mci_rescan_card(sdc_id, 0);
#endif /* CUSTOMER_HW */
        WL_ERROR(("=========== WLAN placed in POWER OFF ========\n"));
        break;

    case WLAN_POWER_ON:
        WL_TRACE(("%s: call customer specific GPIO to turn on WL_REG_ON\n",
                  __FUNCTION__));
#ifdef CUSTOMER_HW
        wifi_pm_power(1);
        sw_mci_rescan_card(sdc_id, 1);
        /* Lets customer power to get stable */
#endif /* CUSTOMER_HW */
        mdelay(100);
        WL_ERROR(("=========== WLAN placed in POWER ON ========\n"));
        break;
    }
}
Beispiel #8
0
/* process one pkt send complete */
static void
wlc_olpc_eng_pkt_complete(wlc_info_t *wlc, void *pkt, uint txs)
{
    chanspec_t chanspec;

    wlc_olpc_eng_chan_t* olpc_chan = NULL;
    wlc_txh_info_t tx_info;
    int err;
    uint8 coreMask;
    uint8 cidx = 0;

    wlc_get_txh_info(wlc, pkt, &tx_info);

    /* one calibration packet was finished */
    /* look at packet header to find - channel, antenna, etc. */
    chanspec = wlc_txh_get_chanspec(wlc, &tx_info);
    olpc_chan = wlc_olpc_get_chan_ex(wlc, chanspec, &err, FALSE);
    WL_OLPC_ENTRY(wlc->olpc_info, ("%s\n", __FUNCTION__));

    if (!olpc_chan || err != BCME_OK) {
        WL_OLPC_DBG(wlc->olpc_info, ("%s: err: NO-OP chanspec=%x\n",
                                     __FUNCTION__, chanspec));
        return;
    }
    if (olpc_chan->cal_pkts_outstanding) {
        olpc_chan->cal_pkts_outstanding--;
    }
    if (olpc_chan->cores_cal_active == 0) {
        WL_OLPC_DBG(wlc->olpc_info, ("%s: NO-OP (no cal was active) chanspec=%x\n",
                                     __FUNCTION__, chanspec));
        goto pkt_complete_done;
    }

    WL_OLPC_DBG(wlc->olpc_info, ("%s: entry status=%d\n", __FUNCTION__, txs));

    /* get core number */
    coreMask = (tx_info.PhyTxControlWord0 & D11AC_PHY_TXC_CORE_MASK) >>
               (D11AC_PHY_TXC_CORE_SHIFT);
    cidx = WL_OLPC_ANT_TO_CIDX(coreMask);

    WL_OLPC_DBG(wlc->olpc_info, ("%s: coreNum=%x\n", __FUNCTION__, coreMask));

    /* decrement counters */
    if (olpc_chan->pkts_sent[cidx]) {
        olpc_chan->pkts_sent[cidx]--;
    } else {
        WL_NONE(("wl%d: %s: tried decrementing counter of 0, idx=%d\n",
                 wlc->pub->unit, __FUNCTION__, WL_OLPC_ANT_TO_CIDX(coreMask)));
    }
    /* if done on core, update info */
    if (olpc_chan->pkts_sent[cidx] == 0) {
        olpc_chan->cores_cal_active &= ~coreMask;
        olpc_chan->cores_cal |= coreMask;
        olpc_chan->cores_cal_to_cmplt |= coreMask;
#if WL_OLPC_IOVARS_ENAB
        olpc_chan->cores_cal_pkts_sent |= coreMask;
#endif /* WL_OLPC_IOVARS_ENAB */

        WL_OLPC(wlc->olpc_info, ("%s: exit: open loop phy CAL done mask=%x!\n",
                                 __FUNCTION__, coreMask));
        WL_OLPC(wlc->olpc_info, ("%s: exit: open loop phy CAL done done=%x active=%x!\n",
                                 __FUNCTION__, olpc_chan->cores_cal, olpc_chan->cores_cal_active));
    }
#if WL_OLPC_IOVARS_ENAB
    if (olpc_chan->cores_cal == wlc->stf->hw_txchain) {
        WL_OLPC(wlc->olpc_info, ("%s: exit: open loop phy CAL done for all chains!\n",
                                 __FUNCTION__));
    }
#endif /* WLTEST || BCMDBG */
    if (olpc_chan->cores_cal_active == 0) {
        WL_OLPC(wlc->olpc_info, ("%s: no more cores w/ cal active!\n", __FUNCTION__));
        /* cache calibration results so following ops don't mess it up */
#if (defined(PHYCAL_CACHING) || defined(WLMCHAN))
#ifndef WLC_HIGH_ONLY
        if (!wlc_phy_get_chanctx((phy_info_t *)wlc->band->pi, wlc->chanspec))
            wlc_phy_create_chanctx(wlc->band->pi, wlc->chanspec);
#endif /* WLC_HIGH_ONLY */
        wlc_phy_cal_cache((wlc_phy_t *)wlc->band->pi);
#endif /* PHYCAL_CACHING || WLMCHAN */

        /* execute these for now, coz cal is over */
        wlc_olpc_stf_override_revert(wlc);

#ifdef WLTXPWR_CACHE
        wlc_phy_txpwr_cache_invalidate(wlc_phy_get_txpwr_cache(wlc->band->pi));
#endif	/* WLTXPWR_CACHE */
#ifdef WLC_HIGH_ONLY
        wlc_bmac_phy_txpwr_cache_invalidate(wlc->hw);
#endif		/* restore cal cache to what it was prior to doing txpwr limit */
#if (defined(PHYCAL_CACHING) || defined(WLMCHAN))
        if ((err = wlc_phy_cal_cache_return((wlc_phy_t *)wlc->band->pi)) != BCME_OK) {
            WL_ERROR(("wl%d:%s: error from wlc_phy_cal_cache_restore=%d\n",
                      wlc->pub->unit, __FUNCTION__, err));
            /* mark as not calibrated - calibration values hosed */
            olpc_chan->cores_cal = 0;
        }
        if (err == BCME_OK ||
#if WL_OLPC_IOVARS_ENAB
                olpc_chan->dbg_mode ||
#endif /* WL_OLPC_IOVARS_ENAB */
                FALSE) {
            /* inform the phy we are calibrated */
            /* if dbg mode is set, we ignore cal cache errors and tell the phy */
            /* to use dbg storage for cal result */
            wlc_phy_update_olpc_cal((wlc_phy_t *)wlc->band->pi, TRUE,
#if WL_OLPC_IOVARS_ENAB
                                    olpc_chan->dbg_mode);
#else
                                    FALSE);
#endif /* WL_OLPC_IOVARS_ENAB */
        }
Beispiel #9
0
/* decode icon metadata */
static int pktDecodeHspotAnqpIconMetadata(bcm_decode_t *pkt,
	bcm_decode_hspot_anqp_icon_metadata_t *icon)
{

	if (!bcm_decode_le16(pkt, &icon->width)) {
		WL_ERROR(("decode error\n"));
		return FALSE;
	}
	if (!bcm_decode_le16(pkt, &icon->height)) {
		WL_ERROR(("decode error\n"));
		return FALSE;
	}
	if (!bcm_decode_bytes(pkt, VENUE_LANGUAGE_CODE_SIZE, (uint8 *)icon->lang)) {
		WL_ERROR(("bcm_decode_bytes failed"));
		return FALSE;
	}
	icon->lang[VENUE_LANGUAGE_CODE_SIZE] = 0;
	if (!bcm_decode_byte(pkt, &icon->typeLength)) {
		WL_ERROR(("decode error\n"));
		return FALSE;
	}
	if (icon->typeLength > bcm_decode_remaining(pkt)) {
		WL_ERROR(("type length exceeds packet %d > %d\n",
			icon->typeLength, bcm_decode_remaining(pkt)));
		return FALSE;
	}
	if (icon->typeLength > BCM_DECODE_HSPOT_ANQP_MAX_ICON_TYPE_LENGTH) {
		WL_ERROR(("type exceeds buffer %d > %d\n",
			icon->typeLength, BCM_DECODE_HSPOT_ANQP_MAX_ICON_TYPE_LENGTH));
		return FALSE;
	}
	if (!bcm_decode_bytes(pkt, icon->typeLength, (uint8 *)icon->type)) {
		WL_ERROR(("bcm_decode_bytes failed"));
		return FALSE;
	}
	icon->type[icon->typeLength] = 0;

	if (!bcm_decode_byte(pkt, &icon->filenameLength)) {
		WL_ERROR(("decode error\n"));
		return FALSE;
	}
	if (icon->filenameLength > bcm_decode_remaining(pkt)) {
		WL_ERROR(("filename length exceeds packet %d > %d\n",
			icon->filenameLength, bcm_decode_remaining(pkt)));
		return FALSE;
	}
	if (icon->filenameLength > BCM_DECODE_HSPOT_ANQP_MAX_ICON_FILENAME_LENGTH) {
		WL_ERROR(("filename exceeds buffer %d > %d\n",
			icon->filenameLength, BCM_DECODE_HSPOT_ANQP_MAX_ICON_FILENAME_LENGTH));
		return FALSE;
	}
	if (!bcm_decode_bytes(pkt, icon->filenameLength, (uint8 *)icon->filename)) {
		WL_ERROR(("bcm_decode_bytes failed"));
		return FALSE;
	}
	icon->filename[icon->filenameLength] = 0;

	return TRUE;
}
Beispiel #10
0
/* Customer function to control hw specific wlan gpios */
void
dhd_customer_gpio_wlan_ctrl(int onoff)
{
	switch (onoff) {
		case WLAN_RESET_OFF:
			WL_TRACE(("%s: call customer specific GPIO to insert WLAN RESET\n",
				__FUNCTION__));
#ifdef CUSTOMER_HW_SAMSUNG
			//bcm_wlan_power_off(2);
                        wlan_setup_power(0, 2);
#endif /* CUSTOMER_HW */
#ifdef CUSTOMER_HW
			bcm_wlan_power_off(2);
#endif /* CUSTOMER_HW */
#ifdef CUSTOMER_HW2
			wifi_set_power(0, 0);
#endif
			WL_ERROR(("=========== WLAN placed in RESET ========\n"));
		break;

		case WLAN_RESET_ON:
			WL_TRACE(("%s: callc customer specific GPIO to remove WLAN RESET\n",
				__FUNCTION__));
#ifdef CUSTOMER_HW_SAMSUNG
			//bcm_wlan_power_on(2);
                        wlan_setup_power(1, 2);
#endif /* CUSTOMER_HW */
#ifdef CUSTOMER_HW
			bcm_wlan_power_on(2);
#endif /* CUSTOMER_HW */
#ifdef CUSTOMER_HW2
			wifi_set_power(1, 0);
#endif
			WL_ERROR(("=========== WLAN going back to live  ========\n"));
		break;

		case WLAN_POWER_OFF:
			WL_TRACE(("%s: call customer specific GPIO to turn off WL_REG_ON\n",
				__FUNCTION__));
#ifdef CUSTOMER_HW_SAMSUNG
			//bcm_wlan_power_off(1);
                        wlan_setup_power(0, 1);
#endif /* CUSTOMER_HW */
#ifdef CUSTOMER_HW
			bcm_wlan_power_off(1);
#endif /* CUSTOMER_HW */
		break;

		case WLAN_POWER_ON:
			WL_TRACE(("%s: call customer specific GPIO to turn on WL_REG_ON\n",
				__FUNCTION__));
#ifdef CUSTOMER_HW_SAMSUNG
			//bcm_wlan_power_on(1);
                        wlan_setup_power(1, 1);
#endif /* CUSTOMER_HW */
#ifdef CUSTOMER_HW
			bcm_wlan_power_on(1);
			/* Lets customer power to get stable */
			OSL_DELAY(50);
#endif /* CUSTOMER_HW */
		break;
	}
}
static void
wl_ops_bss_info_changed(struct ieee80211_hw *hw,
			struct ieee80211_vif *vif,
			struct ieee80211_bss_conf *info, u32 changed)
{
	struct wl_info *wl = HW_TO_WL(hw);
	int val;

	if (changed & BSS_CHANGED_ASSOC) {
		/* association status changed (associated/disassociated)
		 * also implies a change in the AID.
		 */
		WL_ERROR("%s: %s: %sassociated\n", KBUILD_MODNAME, __func__,
			 info->assoc ? "" : "dis");
		wlc_associate_upd(wl->wlc, info->assoc);
	}
	if (changed & BSS_CHANGED_ERP_CTS_PROT) {
		/* CTS protection changed */
		WL_ERROR("%s: use_cts_prot: %s (implement)\n", __func__,
			info->use_cts_prot ? "true" : "false");
	}
	if (changed & BSS_CHANGED_ERP_PREAMBLE) {
		/* preamble changed */
		WL_ERROR("%s: short preamble: %s (implement)\n", __func__,
			info->use_short_preamble ? "true" : "false");
	}
	if (changed & BSS_CHANGED_ERP_SLOT) {
		/* slot timing changed */
		if (info->use_short_slot)
			val = 1;
		else
			val = 0;
		WL_LOCK(wl);
		wlc_set(wl->wlc, WLC_SET_SHORTSLOT_OVERRIDE, val);
		WL_UNLOCK(wl);
	}

	if (changed & BSS_CHANGED_HT) {
		/* 802.11n parameters changed */
		u16 mode = info->ht_operation_mode;
		WL_NONE("%s: HT mode: 0x%04X\n", __func__, mode);
		wlc_protection_upd(wl->wlc, WLC_PROT_N_CFG,
			mode & IEEE80211_HT_OP_MODE_PROTECTION);
		wlc_protection_upd(wl->wlc, WLC_PROT_N_NONGF,
			mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
		wlc_protection_upd(wl->wlc, WLC_PROT_N_OBSS,
			mode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT);
	}
	if (changed & BSS_CHANGED_BASIC_RATES) {
		/* Basic rateset changed */
		WL_ERROR("%s: Need to change Basic Rates: 0x%x (implement)\n",
			 __func__, (u32) info->basic_rates);
	}
	if (changed & BSS_CHANGED_BEACON_INT) {
		/* Beacon interval changed */
		WL_NONE("%s: Beacon Interval: %d\n",
			__func__, info->beacon_int);
		wlc_set(wl->wlc, WLC_SET_BCNPRD, info->beacon_int);
	}
	if (changed & BSS_CHANGED_BSSID) {
		/* BSSID changed, for whatever reason (IBSS and managed mode) */
		WL_NONE("%s: new BSSID: aid %d  bss:%pM\n", __func__,
			info->aid, info->bssid);
		WL_LOCK(wl);
		wlc_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET,
				  info->bssid);
		WL_UNLOCK(wl);
	}
	if (changed & BSS_CHANGED_BEACON) {
		/* Beacon data changed, retrieve new beacon (beaconing modes) */
		WL_ERROR("%s: beacon changed\n", __func__);
	}
	if (changed & BSS_CHANGED_BEACON_ENABLED) {
		/* Beaconing should be enabled/disabled (beaconing modes) */
		WL_ERROR("%s: Beacon enabled: %s\n", __func__,
			 info->enable_beacon ? "true" : "false");
	}
	if (changed & BSS_CHANGED_CQM) {
		/* Connection quality monitor config changed */
		WL_ERROR("%s: cqm change: threshold %d, hys %d (implement)\n",
			__func__, info->cqm_rssi_thold, info->cqm_rssi_hyst);
	}
	if (changed & BSS_CHANGED_IBSS) {
		/* IBSS join status changed */
		WL_ERROR("%s: IBSS joined: %s (implement)\n", __func__,
			info->ibss_joined ? "true" : "false");
	}
	if (changed & BSS_CHANGED_ARP_FILTER) {
		/* Hardware ARP filter address list or state changed */
		WL_ERROR("%s: arp filtering: enabled %s, count %d (implement)\n",
			__func__, info->arp_filter_enabled ? "true" : "false",
			info->arp_addr_cnt);
	}
	if (changed & BSS_CHANGED_QOS) {
		/*
		 * QoS for this association was enabled/disabled.
		 * Note that it is only ever disabled for station mode.
		 */
		WL_ERROR("%s: qos enabled: %s (implement)\n", __func__,
			info->qos ? "true" : "false");
	}
	if (changed & BSS_CHANGED_IDLE) {
		/* Idle changed for this BSS/interface */
		WL_ERROR("%s: BSS idle: %s (implement)\n", __func__,
			info->idle ? "true" : "false");
	}
	return;
}
static int wl_ops_config(struct ieee80211_hw *hw, u32 changed)
{
	struct ieee80211_conf *conf = &hw->conf;
	struct wl_info *wl = HW_TO_WL(hw);
	int err = 0;
	int new_int;

	WL_LOCK(wl);
	if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
		if (wlc_iovar_setint
		    (wl->wlc, "bcn_li_bcn", conf->listen_interval)) {
			WL_ERROR("%s: Error setting listen_interval\n",
				 __func__);
			err = -EIO;
			goto config_out;
		}
		wlc_iovar_getint(wl->wlc, "bcn_li_bcn", &new_int);
		ASSERT(new_int == conf->listen_interval);
	}
	if (changed & IEEE80211_CONF_CHANGE_MONITOR)
		WL_ERROR("%s: change monitor mode: %s (implement)\n", __func__,
			 conf->flags & IEEE80211_CONF_MONITOR ?
				"true" : "false");
	if (changed & IEEE80211_CONF_CHANGE_PS)
		WL_ERROR("%s: change power-save mode: %s (implement)\n",
			 __func__, conf->flags & IEEE80211_CONF_PS ?
				"true" : "false");

	if (changed & IEEE80211_CONF_CHANGE_POWER) {
		if (wlc_iovar_setint
		    (wl->wlc, "qtxpower", conf->power_level * 4)) {
			WL_ERROR("%s: Error setting power_level\n", __func__);
			err = -EIO;
			goto config_out;
		}
		wlc_iovar_getint(wl->wlc, "qtxpower", &new_int);
		if (new_int != (conf->power_level * 4))
			WL_ERROR("%s: Power level req != actual, %d %d\n",
				 __func__, conf->power_level * 4, new_int);
	}
	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
		err = ieee_set_channel(hw, conf->channel, conf->channel_type);
	}
	if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
		if (wlc_set
		    (wl->wlc, WLC_SET_SRL,
		     conf->short_frame_max_tx_count) < 0) {
			WL_ERROR("%s: Error setting srl\n", __func__);
			err = -EIO;
			goto config_out;
		}
		if (wlc_set(wl->wlc, WLC_SET_LRL, conf->long_frame_max_tx_count)
		    < 0) {
			WL_ERROR("%s: Error setting lrl\n", __func__);
			err = -EIO;
			goto config_out;
		}
	}

 config_out:
	WL_UNLOCK(wl);
	return err;
}
/*
 * precondition: perimeter lock has been acquired
 */
void wl_txflowcontrol(struct wl_info *wl, struct wl_if *wlif, bool state,
		      int prio)
{
	WL_ERROR("Shouldn't be here %s\n", __func__);
}
/* Function to get custom MAC address */
int
dhd_custom_get_mac_address(unsigned char *buf)
{
	int ret = 0;

	WL_TRACE(("%s Enter\n", __FUNCTION__));
	if (!buf)
		return -EINVAL;

	/* Customer access to MAC address stored outside of DHD driver */
#if defined(CUSTOMER_HW2) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
	ret = wifi_get_mac_addr(buf);
#endif

//#ifdef EXAMPLE_GET_MAC
	/* EXAMPLE code */
	{
	    
	    char text[128];
	    int len;
	    void *image = NULL;
	    char *p_start=NULL;  
        char text_addr[12];
         
		struct ether_addr ea_example = {{0xc8, 0x56, 0x78, 0x9a, 0xbc, 0xde}};
        

		bcopy((char *)&ea_example, buf, sizeof(struct ether_addr));
         buf[4]=random32()&0xff;
         buf[5]=random32()&0xff;
        image = dhd_os_open_image("/persist/WCNSS_qcom_cfg.ini");
        if (image == NULL)
            WL_ERROR(("%s can't open wncss config file!!!\n", __FUNCTION__));  

        	/* Download image */
#if defined(NDISVER) && (NDISVER >= 0x0630)
	while ((len = dhd_os_get_image_block((char*)text, 127, image, FALSE))) {
#else
	while ((len = dhd_os_get_image_block((char*)text, 127, image))) {
#endif /* NDSIVER && (NDISVER >= 0x0680) */
		if (len < 0) {
			  WL_ERROR(("%s get address data failed (%d)\n", __FUNCTION__,len));
			    goto err;;
			
		}
        if(text[0]=='#')
            continue;
         if ((p_start=strstr(text, "Intf0MacAddress")))
            {
                if ((p_start=strstr(text, "="))){

                                        
                      scru_ascii_2_hex (p_start+1, 12,text_addr);  
 
                        memcpy(buf,text_addr,6);   
                     
                        printk("get wifi NV address=%x:%x:%x:%x:%x:%x\n",buf[0],buf[1],buf[2],buf[3],buf[4],buf[5]); 
                        ret = 0;      
                break;
                    }
            }

         
       }
    err:
        if (image){
		dhd_os_close_image(image);
          
            }
        
	}
//#endif /* EXAMPLE_GET_MAC */

	return ret;
}
#endif /* GET_CUSTOM_MAC_ENABLE */

/* Customized Locale table : OPTIONAL feature */
const struct cntry_locales_custom translate_custom_table[] = {
/* Table should be filled out based on custom platform regulatory requirement */
#ifdef EXAMPLE_TABLE
	{"",   "XY", 4},  /* Universal if Country code is unknown or empty */
	{"US", "US", 69}, /* input ISO "US" to : US regrev 69 */
	{"CA", "US", 69}, /* input ISO "CA" to : US regrev 69 */
	{"EU", "EU", 5},  /* European union countries to : EU regrev 05 */
	{"AT", "EU", 5},
	{"BE", "EU", 5},
	{"BG", "EU", 5},
	{"CY", "EU", 5},
	{"CZ", "EU", 5},
	{"DK", "EU", 5},
	{"EE", "EU", 5},
	{"FI", "EU", 5},
	{"FR", "EU", 5},
	{"DE", "EU", 5},
	{"GR", "EU", 5},
	{"HU", "EU", 5},
	{"IE", "EU", 5},
	{"IT", "EU", 5},
	{"LV", "EU", 5},
	{"LI", "EU", 5},
	{"LT", "EU", 5},
	{"LU", "EU", 5},
	{"MT", "EU", 5},
	{"NL", "EU", 5},
	{"PL", "EU", 5},
	{"PT", "EU", 5},
	{"RO", "EU", 5},
	{"SK", "EU", 5},
	{"SI", "EU", 5},
	{"ES", "EU", 5},
	{"SE", "EU", 5},
	{"GB", "EU", 5},
	{"KR", "XY", 3},
	{"AU", "XY", 3},
	{"CN", "XY", 3}, /* input ISO "CN" to : XY regrev 03 */
	{"TW", "XY", 3},
	{"AR", "XY", 3},
	{"MX", "XY", 3},
	{"IL", "IL", 0},
	{"CH", "CH", 0},
	{"TR", "TR", 0},
	{"NO", "NO", 0},
#endif /* EXMAPLE_TABLE */
};


/* Customized Locale convertor
*  input : ISO 3166-1 country abbreviation
*  output: customized cspec
*/
void get_customized_country_code(char *country_iso_code, wl_country_t *cspec)
{
#if defined(CUSTOMER_HW2) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39))

	struct cntry_locales_custom *cloc_ptr;

	if (!cspec)
		return;

	cloc_ptr = wifi_get_country_code(country_iso_code);
	if (cloc_ptr) {
		strlcpy(cspec->ccode, cloc_ptr->custom_locale, WLC_CNTRY_BUF_SZ);
		cspec->rev = cloc_ptr->custom_locale_rev;
	}
	return;
#else
	int size, i;

	size = ARRAYSIZE(translate_custom_table);

	if (cspec == 0)
		 return;

	if (size == 0)
		 return;

	for (i = 0; i < size; i++) {
		if (strcmp(country_iso_code, translate_custom_table[i].iso_abbrev) == 0) {
			memcpy(cspec->ccode,
				translate_custom_table[i].custom_locale, WLC_CNTRY_BUF_SZ);
			cspec->rev = translate_custom_table[i].custom_locale_rev;
			return;
		}
	}
#ifdef EXAMPLE_TABLE
	/* if no country code matched return first universal code from translate_custom_table */
	memcpy(cspec->ccode, translate_custom_table[0].custom_locale, WLC_CNTRY_BUF_SZ);
	cspec->rev = translate_custom_table[0].custom_locale_rev;
#endif /* EXMAPLE_TABLE */
	return;
#endif /* defined(CUSTOMER_HW2) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)) */
}
/* Customer function to control hw specific wlan gpios */
void
dhd_customer_gpio_wlan_ctrl(int onoff)
{

	switch (onoff) {
		case WLAN_RESET_OFF:
		{
			WL_TRACE(("%s: call customer specific GPIO to insert WLAN RESET\n", __FUNCTION__));
			mmc_pm_gpio_ctrl("bcm40181_shdn", 0);
			mmc_pm_gpio_ctrl("bcm40181_vcc_en", 0);
			mmc_pm_gpio_ctrl("bcm40181_vdd_en", 0);
			printk("[bcm40181]: bcm40181_shdn=>0 !!\n");

#ifdef CUSTOMER_HW
			bcm_wlan_power_off(2);
#endif /* CUSTOMER_HW */

#ifdef CONFIG_MACH_MAHIMAHI
			wifi_set_power(0, 0);
#endif
			WL_ERROR(("=========== WLAN placed in RESET ========\n"));
		}
		break;

		case WLAN_RESET_ON:
		{
			WL_TRACE(("%s: callc customer specific GPIO to remove WLAN RESET\n", __FUNCTION__));
			mmc_pm_gpio_ctrl("bcm40181_vcc_en", 1);
			udelay(100);
			mmc_pm_gpio_ctrl("bcm40181_shdn", 1);
			udelay(50);
			mmc_pm_gpio_ctrl("bcm40181_vdd_en", 1);
			printk("[bcm40181]: bcm40181_shdn=>1 !!\n");

#ifdef CUSTOMER_HW
			bcm_wlan_power_on(2);
#endif /* CUSTOMER_HW */

#ifdef CONFIG_MACH_MAHIMAHI
			wifi_set_power(1, 0);
#endif
			WL_ERROR(("=========== WLAN going back to live  ========\n"));
		}
		break;

		case WLAN_POWER_OFF:
		{
			WL_TRACE(("%s: call customer specific GPIO to turn off WL_REG_ON\n", __FUNCTION__));
			mmc_pm_gpio_ctrl("bcm40181_shdn", 0);
			mmc_pm_gpio_ctrl("bcm40181_vcc_en", 0);
			mmc_pm_gpio_ctrl("bcm40181_vdd_en", 0);
			sunximmc_rescan_card(3, 0);

#ifdef CUSTOMER_HW
			bcm_wlan_power_off(1);
#endif /* CUSTOMER_HW */
		}
		break;

		case WLAN_POWER_ON:
		{
			WL_TRACE(("%s: call customer specific GPIO to turn on WL_REG_ON\n", __FUNCTION__));
			mmc_pm_gpio_ctrl("bcm40181_vcc_en", 1);
			udelay(100);
			mmc_pm_gpio_ctrl("bcm40181_shdn", 1);
			udelay(50);
			mmc_pm_gpio_ctrl("bcm40181_vdd_en", 1);			

#ifdef CUSTOMER_HW
			bcm_wlan_power_on(1);
#endif /* CUSTOMER_HW */
			/* Lets customer power to get stable */
			OSL_DELAY(200);
            sunximmc_rescan_card(3, 1);
		}
		break;
	}
}
Beispiel #16
0
/* Customer function to control hw specific wlan gpios */
void
dhd_customer_gpio_wlan_ctrl(int onoff)
{
	switch (onoff) {
		case WLAN_RESET_OFF:
			WL_TRACE(("%s: call customer specific GPIO to insert WLAN RESET\n",
				__FUNCTION__));
#ifdef CUSTOMER_HW
			bcm_wlan_power_off(2);
#endif /* CUSTOMER_HW */
#ifdef CUSTOMER_HW2
			wifi_set_power(0, 0);
#endif
#ifdef  CONFIG_LCT_AE770
			gpio_set_value(116, 0); //116 wifi pwd for ae770 //21 //123 is for aw70 project
#else
                    gpio_set_value(21, 0);  //123 is for aw70 project
#endif        
			WL_ERROR(("=========== WLAN placed in RESET ========\n"));
		break;

		case WLAN_RESET_ON:
			WL_TRACE(("%s: callc customer specific GPIO to remove WLAN RESET\n",
				__FUNCTION__));
#ifdef CUSTOMER_HW
			bcm_wlan_power_on(2);
#endif /* CUSTOMER_HW */
#ifdef CUSTOMER_HW2
			wifi_set_power(1, 0);
#endif
#ifdef  CONFIG_LCT_AE770
			gpio_set_value(116, 1); //116 wifi pwd for ae770 //21 //123 is for aw70 project
#else
                    gpio_set_value(21, 1);  //123 is for aw70 project
#endif        
			OSL_DELAY(200);
			WL_ERROR(("=========== WLAN going back to live  ========\n"));
		break;

		case WLAN_POWER_OFF:
			WL_TRACE(("%s: call customer specific GPIO to turn off WL_REG_ON\n",
				__FUNCTION__));
#ifdef CUSTOMER_HW
			bcm_wlan_power_off(1);
#endif /* CUSTOMER_HW */
#ifdef  CONFIG_LCT_AE770
			gpio_set_value(116, 0); //116 wifi pwd for ae770 //21 //123 is for aw70 project
			//wifi_detect_change(1);

#else
                    gpio_set_value(21, 0);  //123 is for aw70 project
                    wifi_detect_change(1);
#endif        
		break;

		case WLAN_POWER_ON:
			WL_TRACE(("%s: call customer specific GPIO to turn on WL_REG_ON\n",
				__FUNCTION__));
#ifdef CUSTOMER_HW
			bcm_wlan_power_on(1);
#endif /* CUSTOMER_HW */
#ifdef  CONFIG_LCT_AE770
			gpio_set_value(116, 1); //116 wifi pwd for ae770 //21 //123 is for aw70 project
#else
                    gpio_set_value(21, 1);  //123 is for aw70 project
#endif          
			/* Lets customer power to get stable */
			OSL_DELAY(200);
			wifi_detect_change(1);
		break;
	}
}
Beispiel #17
0
/* Customer function to control hw specific wlan gpios */
void
dhd_customer_gpio_wlan_ctrl(int onoff)
{
	switch (onoff) {
		case WLAN_RESET_OFF:
			WL_TRACE(("%s: call customer specific GPIO to insert WLAN RESET\n",
				__FUNCTION__));
#ifdef CUSTOMER_HW
			bcm_wlan_power_off(2);
#endif /* CUSTOMER_HW */
#ifdef CONFIG_MACH_MAHIMAHI
			wifi_set_power(0, 0);
#elif defined(CUSTOMER_HW_PT)
			gpio_set_value(dhd_wl_reset_gpio, 0);
			printk("WLAN_RESET_OFF[%d]\n",
				gpio_get_value(dhd_wl_reset_gpio));
#endif
			WL_ERROR(("=========== WLAN placed in RESET ========\n"));
		break;

		case WLAN_RESET_ON:
			WL_TRACE(("%s: callc customer specific GPIO to remove WLAN RESET\n",
				__FUNCTION__));
#ifdef CUSTOMER_HW
			bcm_wlan_power_on(2);
#endif /* CUSTOMER_HW */
#ifdef CONFIG_MACH_MAHIMAHI
			wifi_set_power(1, 0);
#elif defined(CUSTOMER_HW_PT)
			gpio_set_value(dhd_wl_reset_gpio, 1);
			printk("WLAN_RESET_ON[%d]\n",
				gpio_get_value(dhd_wl_reset_gpio));
#endif
			WL_ERROR(("=========== WLAN going back to live  ========\n"));
		break;

		case WLAN_POWER_OFF:
			WL_TRACE(("%s: call customer specific GPIO to turn off WL_REG_ON\n",
				__FUNCTION__));
#ifdef CUSTOMER_HW
			bcm_wlan_power_off(1);
#endif /* CUSTOMER_HW */
#if defined(CUSTOMER_HW_PT) && !defined(CONFIG_MACH_MAHIMAHI)
			gpio_set_value(dhd_wl_reset_gpio, 0);
			printk("WLAN_POWER_OFF[%d]\n",
				gpio_get_value(dhd_wl_reset_gpio));
#endif
		break;

		case WLAN_POWER_ON:
			WL_TRACE(("%s: call customer specific GPIO to turn on WL_REG_ON\n",
				__FUNCTION__));
#ifdef CUSTOMER_HW
			bcm_wlan_power_on(1);
#endif /* CUSTOMER_HW */
#if defined(CUSTOMER_HW_PT) && !defined(CONFIG_MACH_MAHIMAHI)
			gpio_set_value(dhd_wl_reset_gpio, 1);
			printk("WLAN_POWER_ON[%d]\n",
				gpio_get_value(dhd_wl_reset_gpio));
#endif
			/* Lets customer power to get stable */
			OSL_DELAY(200);
		break;
	}
}
static void wl_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf)
{
	WL_ERROR("%s: Enter\n", __func__);
	return;
}
Beispiel #19
0
/* Customer function to control hw specific wlan gpios */
void
dhd_customer_gpio_wlan_ctrl(int onoff)
{
	switch (onoff) {
		case WLAN_RESET_OFF:
			WL_TRACE(("%s: call customer specific GPIO to insert WLAN RESET\n",
				__FUNCTION__));
#ifdef CUSTOMER_HW
			bcm_wlan_power_off(2);
#endif /* CUSTOMER_HW */
#ifdef CUSTOMER_HW2
			wifi_set_power(0, 0);
#endif
			WL_ERROR(("=========== WLAN placed in RESET ========\n"));

#if !defined(CONFIG_WIFI_CONTROL_FUNC)
			gpio_tlmm_config(GPIO_CFG(CONFIG_BCMDHD_GPIO_WL_RESET, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), GPIO_CFG_ENABLE);
			
			gpio_set_value(CONFIG_BCMDHD_GPIO_WL_RESET, 0);
			mdelay(200);

			disable_irq(gpio_to_irq(CONFIG_BCMDHD_GPIO_WL_RESET));
			mdelay(200);
#endif			
		break;

		case WLAN_RESET_ON:
			WL_TRACE(("%s: callc customer specific GPIO to remove WLAN RESET\n",
				__FUNCTION__));
#ifdef CUSTOMER_HW
			bcm_wlan_power_on(2);
#endif /* CUSTOMER_HW */
#ifdef CUSTOMER_HW2
			wifi_set_power(1, 0);
#endif
			WL_ERROR(("=========== WLAN going back to live  ========\n"));
#if !defined(CONFIG_WIFI_CONTROL_FUNC)
			gpio_tlmm_config(GPIO_CFG(CONFIG_BCMDHD_GPIO_WL_RESET, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), GPIO_CFG_ENABLE);
			
			gpio_set_value(CONFIG_BCMDHD_GPIO_WL_RESET, 1);
			mdelay(200);
				
			enable_irq(gpio_to_irq(CONFIG_BCMDHD_GPIO_WL_RESET));
			mdelay(200);
#endif
		break;

		case WLAN_POWER_OFF:
			WL_TRACE(("%s: call customer specific GPIO to turn off WL_REG_ON\n",
				__FUNCTION__));
#ifdef CUSTOMER_HW
			bcm_wlan_power_off(1);
#endif /* CUSTOMER_HW */

		break;

		case WLAN_POWER_ON:
			WL_TRACE(("%s: call customer specific GPIO to turn on WL_REG_ON\n",
				__FUNCTION__));
#ifdef CUSTOMER_HW
			bcm_wlan_power_on(1);
			/* Lets customer power to get stable */
			OSL_DELAY(200);
#endif /* CUSTOMER_HW */

		break;
	}
}
static u64 wl_ops_get_tsf(struct ieee80211_hw *hw)
{
	WL_ERROR("%s: Enter\n", __func__);
	return 0;
}
Beispiel #21
0
/* decode OSU provider list */
int bcm_decode_hspot_anqp_osu_provider_list(bcm_decode_t *pkt,
	bcm_decode_hspot_anqp_osu_provider_list_t *list)
{
	int len;
	int i;

	WL_PRPKT("packet for hotspot OSU provider list decoding",
		bcm_decode_current_ptr(pkt), bcm_decode_remaining(pkt));

	memset(list, 0, sizeof(*list));

	if (bcm_decode_is_zero_length(pkt))
		return TRUE;

	/* decode OSU SSID */
	if (!bcm_decode_byte(pkt, &list->osuSsidLength)) {
		WL_ERROR(("decode error\n"));
		return FALSE;
	}
	len = list->osuSsidLength;
	if (len > BCM_DECODE_HSPOT_ANQP_MAX_OSU_SSID_LENGTH) {
		WL_ERROR(("length exceeds maximum %d > %d\n",
			list->osuSsidLength,
			BCM_DECODE_HSPOT_ANQP_MAX_OSU_SSID_LENGTH));
		return FALSE;
	}
	if (list->osuSsidLength > bcm_decode_remaining(pkt)) {
		WL_ERROR(("length exceeds packet %d > %d\n",
			list->osuSsidLength, bcm_decode_remaining(pkt)));
		return FALSE;
	}
	if (list->osuSsidLength > 0 &&
		!bcm_decode_bytes(pkt, list->osuSsidLength, list->osuSsid)) {
		WL_ERROR(("bcm_decode_bytes failed"));
		return FALSE;
	}
	list->osuSsid[list->osuSsidLength] = 0;

	/* decode number of OSU providers */
	if (!bcm_decode_byte(pkt, &list->osuProviderCount)) {
		WL_ERROR(("decode error\n"));
		return FALSE;
	}
	if (list->osuProviderCount > BCM_DECODE_HSPOT_ANQP_MAX_OSU_PROVIDER) {
		WL_ERROR(("length exceeds maximum %d > %d\n",
			list->osuProviderCount,
			BCM_DECODE_HSPOT_ANQP_MAX_OSU_PROVIDER));
		return FALSE;
	}

	for (i = 0; i < list->osuProviderCount; i++) {
		bcm_decode_hspot_anqp_osu_provider_t *osu =
			&list->osuProvider[i];
		uint16 osuLength;
		uint16 nameLength;
		int remNameLength;
		uint16 iconLength;
		int remIconLength;
		uint16 descLength;
		int remDescLength;

		/* decode OSU provider length */
		if (!bcm_decode_le16(pkt, &osuLength)) {
			WL_ERROR(("decode error\n"));
			return FALSE;
		}
		if (osuLength > bcm_decode_remaining(pkt)) {
			WL_ERROR(("OSU length exceeds packet %d > %d\n",
				osuLength, bcm_decode_remaining(pkt)));
			return FALSE;
		}

		/* decode OSU friendly name */
		if (!bcm_decode_le16(pkt, &nameLength)) {
			WL_ERROR(("decode error\n"));
			return FALSE;
		}
		if (nameLength > bcm_decode_remaining(pkt)) {
			WL_ERROR(("name length exceeds packet %d > %d\n",
				nameLength, bcm_decode_remaining(pkt)));
			return FALSE;
		}
		remNameLength = nameLength;
		while (remNameLength > 0 &&
			osu->name.numName < BCM_DECODE_HSPOT_ANQP_MAX_OPERATOR_NAME) {
			int startOffset = bcm_decode_offset(pkt);

			if (!pktDecodeHspotAnqpOperatorNameDuple(pkt,
				&osu->name.duple[osu->name.numName])) {
				return FALSE;
			}
			else {
				osu->name.numName++;
			}

			/* update remaining name length */
			remNameLength -= bcm_decode_offset(pkt) - startOffset;
		}

		/* decode OSU server URI */
		if (!bcm_decode_byte(pkt, &osu->uriLength)) {
			WL_ERROR(("decode error\n"));
			return FALSE;
		}
		if (osu->uriLength > BCM_DECODE_HSPOT_ANQP_MAX_URI_LENGTH) {
			WL_ERROR(("URI exceeds buffer %d > %d\n",
				osu->uriLength, BCM_DECODE_HSPOT_ANQP_MAX_URI_LENGTH));
			return FALSE;
		}
		if (osu->uriLength > 0 &&
			!bcm_decode_bytes(pkt, osu->uriLength, (uint8 *)osu->uri)) {
			WL_ERROR(("bcm_decode_bytes failed"));
			return FALSE;
		}
		osu->uri[osu->uriLength] = 0;

		/* decode OSU method */
		if (!bcm_decode_byte(pkt, &osu->methodLength)) {
			WL_ERROR(("decode error\n"));
			return FALSE;
		}
		if (osu->methodLength > BCM_DECODE_HSPOT_ANQP_MAX_METHOD_LENGTH) {
			WL_ERROR(("method exceeds buffer %d > %d\n",
				osu->methodLength, BCM_DECODE_HSPOT_ANQP_MAX_METHOD_LENGTH));
			return FALSE;
		}
		if (!bcm_decode_bytes(pkt, osu->methodLength, (uint8 *)osu->method)) {
			WL_ERROR(("bcm_decode_bytes failed\n"));
			return FALSE;
		}

		/* decode icon metadata */
		if (!bcm_decode_le16(pkt, &iconLength)) {
			WL_ERROR(("decode error\n"));
			return FALSE;
		}
		remIconLength = iconLength;
		while (remIconLength > 0 &&
			osu->iconMetadataCount < BCM_DECODE_HSPOT_ANQP_MAX_ICON_METADATA_LENGTH) {
			int startOffset = bcm_decode_offset(pkt);

			if (!pktDecodeHspotAnqpIconMetadata(pkt,
				&osu->iconMetadata[osu->iconMetadataCount])) {
				return FALSE;
			}
			else {
				osu->iconMetadataCount++;
			}

			/* update remaining name length */
			remIconLength -= bcm_decode_offset(pkt) - startOffset;
		}

		/* decode OSU NAI */
		if (!bcm_decode_byte(pkt, &osu->naiLength)) {
			WL_ERROR(("decode error\n"));
			return FALSE;
		}
		if (osu->naiLength > BCM_DECODE_HSPOT_ANQP_MAX_NAI_LENGTH) {
			WL_ERROR(("NAI exceeds buffer %d > %d\n",
				osu->naiLength, BCM_DECODE_HSPOT_ANQP_MAX_NAI_LENGTH));
			return FALSE;
		}
		if (osu->naiLength > 0 &&
			!bcm_decode_bytes(pkt, osu->naiLength, (uint8 *)osu->nai)) {
			WL_ERROR(("bcm_decode_bytes failed"));
			return FALSE;
		}
		osu->nai[osu->naiLength] = 0;

		/* decode OSU service description */
		if (!bcm_decode_le16(pkt, &descLength)) {
			WL_ERROR(("decode error\n"));
			return FALSE;
		}
		if (descLength > bcm_decode_remaining(pkt)) {
			WL_ERROR(("name length exceeds packet %d > %d\n",
				descLength, bcm_decode_remaining(pkt)));
			return FALSE;
		}
		remDescLength = descLength;
		while (remDescLength > 0 &&
			osu->desc.numName < BCM_DECODE_HSPOT_ANQP_MAX_OPERATOR_NAME) {
			int startOffset = bcm_decode_offset(pkt);

			if (!pktDecodeHspotAnqpOperatorNameDuple(pkt,
				&osu->desc.duple[osu->desc.numName])) {
				return FALSE;
			}
			else {
				osu->desc.numName++;
			}

			/* update remaining name length */
			remDescLength -= bcm_decode_offset(pkt) - startOffset;
		}
	}

	list->isDecodeValid = TRUE;
	return TRUE;
}
/**
 * attach to the WL device.
 *
 * Attach to the WL device identified by vendor and device parameters.
 * regs is a host accessible memory address pointing to WL device registers.
 *
 * wl_attach is not defined as static because in the case where no bus
 * is defined, wl_attach will never be called, and thus, gcc will issue
 * a warning that this function is defined but not used if we declare
 * it as static.
 *
 *
 * is called in wl_pci_probe() context, therefore no locking required.
 */
static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs,
			    uint bustype, void *btparam, uint irq)
{
	struct wl_info *wl;
	int unit, err;

	unsigned long base_addr;
	struct ieee80211_hw *hw;
	u8 perm[ETH_ALEN];

	unit = wl_found;
	err = 0;

	if (unit < 0) {
		WL_ERROR("wl%d: unit number overflow, exiting\n", unit);
		return NULL;
	}

	/* allocate private info */
	hw = pci_get_drvdata(btparam);	/* btparam == pdev */
	wl = hw->priv;
	ASSERT(wl);

	atomic_set(&wl->callbacks, 0);

	/* setup the bottom half handler */
	tasklet_init(&wl->tasklet, wl_dpc, (unsigned long) wl);



	base_addr = regs;

	if (bustype == PCI_BUS) {
		wl->piomode = false;
	} else if (bustype == RPC_BUS) {
		/* Do nothing */
	} else {
		bustype = PCI_BUS;
		WL_TRACE("force to PCI\n");
	}
	wl->bcm_bustype = bustype;

	wl->regsva = ioremap_nocache(base_addr, PCI_BAR0_WINSZ);
	if (wl->regsva == NULL) {
		WL_ERROR("wl%d: ioremap() failed\n", unit);
		goto fail;
	}
	spin_lock_init(&wl->lock);
	spin_lock_init(&wl->isr_lock);

	/* prepare ucode */
	if (wl_request_fw(wl, (struct pci_dev *)btparam) < 0) {
		WL_ERROR("%s: Failed to find firmware usually in %s\n",
			 KBUILD_MODNAME, "/lib/firmware/brcm");
		wl_release_fw(wl);
		wl_remove((struct pci_dev *)btparam);
		goto fail1;
	}

	/* common load-time initialization */
	wl->wlc = wlc_attach((void *)wl, vendor, device, unit, wl->piomode,
			     wl->regsva, wl->bcm_bustype, btparam, &err);
	wl_release_fw(wl);
	if (!wl->wlc) {
		WL_ERROR("%s: wlc_attach() failed with code %d\n",
			 KBUILD_MODNAME, err);
		goto fail;
	}
	wl->pub = wlc_pub(wl->wlc);

	wl->pub->ieee_hw = hw;
	ASSERT(wl->pub->ieee_hw);
	ASSERT(wl->pub->ieee_hw->priv == wl);


	if (wlc_iovar_setint(wl->wlc, "mpc", 0)) {
		WL_ERROR("wl%d: Error setting MPC variable to 0\n", unit);
	}

	/* register our interrupt handler */
	if (request_irq(irq, wl_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) {
		WL_ERROR("wl%d: request_irq() failed\n", unit);
		goto fail;
	}
	wl->irq = irq;

	/* register module */
	wlc_module_register(wl->pub, NULL, "linux", wl, NULL, wl_linux_watchdog,
			    NULL);

	if (ieee_hw_init(hw)) {
		WL_ERROR("wl%d: %s: ieee_hw_init failed!\n", unit, __func__);
		goto fail;
	}

	memcpy(perm, &wl->pub->cur_etheraddr, ETH_ALEN);
	ASSERT(is_valid_ether_addr(perm));
	SET_IEEE80211_PERM_ADDR(hw, perm);

	err = ieee80211_register_hw(hw);
	if (err) {
		WL_ERROR("%s: ieee80211_register_hw failed, status %d\n",
			 __func__, err);
	}

	if (wl->pub->srom_ccode[0])
		err = wl_set_hint(wl, wl->pub->srom_ccode);
	else
		err = wl_set_hint(wl, "US");
	if (err) {
		WL_ERROR("%s: regulatory_hint failed, status %d\n",
			 __func__, err);
	}

	wl_found++;
	return wl;

fail:
	wl_free(wl);
fail1:
	return NULL;
}
Beispiel #23
0
void
dhd_customer_gpio_wlan_ctrl(int onoff)
{
    switch (onoff) {
    case WLAN_RESET_OFF:
        WL_TRACE(("%s: call customer specific GPIO to insert WLAN RESET\n",
                  __FUNCTION__));
#ifdef CUSTOMER_HW
        bcm_wlan_power_off(2);
#endif
#if 1

#if defined(CONFIG_MACH_EVT0) || defined(CONFIG_MACH_EVT0_1) ||defined( CONFIG_MACH_EVB)
        gpio_set_value(78,0);
#elif defined CONFIG_MACH_EVT1
        gpio_set_value(76,0);
#else
        gpio_set_value(76,0);
#endif

        mdelay(100);
#if defined(CONFIG_MACH_EVT0) || defined(CONFIG_MACH_EVT0_1) ||defined( CONFIG_MACH_EVB)
        gpio_set_value(78,1);
#elif defined CONFIG_MACH_EVT1
        gpio_set_value(76,1);
#else
        gpio_set_value(76,1);
#endif

        mdelay(100);

#if defined(CONFIG_MACH_EVT0) || defined(CONFIG_MACH_EVT0_1) ||defined( CONFIG_MACH_EVB)
        gpio_set_value(78,0);
#elif defined CONFIG_MACH_EVT1
        gpio_set_value(76,0);
#else
        gpio_set_value(76,0);
#endif

        mdelay(100);


#if defined(CONFIG_MACH_EVT0) || defined(CONFIG_MACH_EVT0_1) || defined(CONFIG_MACH_EVT1)
        gpio_set_value(147,0);
#elif defined CONFIG_MACH_EVB
        gpio_set_value(142,0);
#else
        gpio_set_value(147,0);
#endif

#endif

        WL_ERROR(("=========== WLAN placed in RESET ========\n"));
        break;

    case WLAN_RESET_ON:
        WL_TRACE(("%s: callc customer specific GPIO to remove WLAN RESET\n",
                  __FUNCTION__));
#ifdef CUSTOMER_HW
        bcm_wlan_power_on(2);
#endif
#if 1
        gpio_tlmm_config(GPIO_CFG(62,1,GPIO_OUTPUT,GPIO_NO_PULL,GPIO_8MA),GPIO_ENABLE);
        gpio_tlmm_config(GPIO_CFG(63,1,GPIO_OUTPUT,GPIO_PULL_UP,GPIO_8MA),GPIO_ENABLE);
        gpio_tlmm_config(GPIO_CFG(64,1,GPIO_OUTPUT,GPIO_PULL_UP,GPIO_4MA),GPIO_ENABLE);
        gpio_tlmm_config(GPIO_CFG(65,1,GPIO_OUTPUT,GPIO_PULL_UP,GPIO_4MA),GPIO_ENABLE);
        gpio_tlmm_config(GPIO_CFG(66,1,GPIO_OUTPUT,GPIO_PULL_UP,GPIO_4MA),GPIO_ENABLE);
        gpio_tlmm_config(GPIO_CFG(67,1,GPIO_OUTPUT,GPIO_PULL_UP,GPIO_4MA),GPIO_ENABLE);
        gpio_tlmm_config(GPIO_CFG(94,0,GPIO_INPUT,GPIO_NO_PULL,GPIO_4MA),GPIO_ENABLE);

#if defined(CONFIG_MACH_EVT0) || defined(CONFIG_MACH_EVT0_1) || defined(CONFIG_MACH_EVT1)
        gpio_tlmm_config(GPIO_CFG(147,0,GPIO_OUTPUT,GPIO_PULL_DOWN,GPIO_2MA),GPIO_ENABLE);
#elif defined CONFIG_MACH_EVB
        gpio_tlmm_config(GPIO_CFG(142,0,GPIO_OUTPUT,GPIO_PULL_DOWN,GPIO_2MA),GPIO_ENABLE);
#else
        gpio_tlmm_config(GPIO_CFG(147,0,GPIO_OUTPUT,GPIO_PULL_DOWN,GPIO_2MA),GPIO_ENABLE);
#endif

#if defined(CONFIG_MACH_EVT0) || defined(CONFIG_MACH_EVT0_1) ||defined( CONFIG_MACH_EVB)
        gpio_tlmm_config(GPIO_CFG(78,0,GPIO_OUTPUT,GPIO_PULL_DOWN,GPIO_2MA),GPIO_ENABLE);
#elif defined CONFIG_MACH_EVT1
        gpio_tlmm_config(GPIO_CFG(76,0,GPIO_OUTPUT,GPIO_PULL_DOWN,GPIO_2MA),GPIO_ENABLE);
#else
        gpio_tlmm_config(GPIO_CFG(76,0,GPIO_OUTPUT,GPIO_PULL_DOWN,GPIO_2MA),GPIO_ENABLE);
#endif

#if !(defined(CONFIG_MACH_EVB))
        gpio_tlmm_config(GPIO_CFG(30,0,GPIO_OUTPUT,GPIO_PULL_DOWN,GPIO_2MA),GPIO_ENABLE);
#endif

#if defined(CONFIG_MACH_EVT0) || defined(CONFIG_MACH_EVT0_1) || defined(CONFIG_MACH_EVT1)
        gpio_set_value(147,1);
#elif defined CONFIG_MACH_EVB
        gpio_set_value(142,1);
#else
        gpio_set_value(147,1);
#endif

        mdelay(100);

#if defined(CONFIG_MACH_EVT0) || defined(CONFIG_MACH_EVT0_1) ||defined( CONFIG_MACH_EVB)
        gpio_set_value(78,1);
#elif defined CONFIG_MACH_EVT1
        gpio_set_value(76,1);
#else
        gpio_set_value(76,1);
#endif

        PM_LOG_EVENT(PM_LOG_ON,PM_LOG_WIFI);

#if !(defined(CONFIG_MACH_EVB))

        if(gpio_get_value(29)==0) {
            gpio_set_value(27,1);
            printk("WLAN init: bt pulse start **************\n");
            mdelay(100);
            gpio_set_value(27,0);
            printk("WLAN init: bt pulse done ***************\n");
        }

#endif


#if !(defined(CONFIG_MACH_EVB))
        gpio_set_value(30,1);
        mdelay(100);
#endif

#endif



        WL_ERROR(("=========== WLAN going back to live  ========\n"));
        break;

    case WLAN_POWER_OFF:
        WL_TRACE(("%s: call customer specific GPIO to turn off WL_REG_ON\n",
                  __FUNCTION__));
#ifdef CUSTOMER_HW
        bcm_wlan_power_off(1);
#endif
        break;

    case WLAN_POWER_ON:
        WL_TRACE(("%s: call customer specific GPIO to turn on WL_REG_ON\n",
                  __FUNCTION__));
#ifdef CUSTOMER_HW
        bcm_wlan_power_on(1);
#endif

        OSL_DELAY(500);
        break;
    }
}
/* Customer function to control hw specific wlan gpios */
void
dhd_customer_gpio_wlan_ctrl(int onoff)
{
	int ret;
	switch (onoff) {
		case WLAN_RESET_OFF:
			WL_TRACE(("%s: call customer specific GPIO to insert WLAN RESET\n",
				__FUNCTION__));
#ifdef CUSTOMER_HW
			bcm_wlan_power_off(2);
#endif /* CUSTOMER_HW */
#ifdef CUSTOMER_HW2
			//wifi_set_power(0, 0);
//			wifi_set_reset(0, 0);
#endif
			WL_ERROR(("=========== WLAN placed in RESET ========\n"));
			ret = IW8101_wlan_power_off(RESET);
			if(ret < 0){
				printk("IW8101_wlan_power_off reset failed");
			}
		break;

		case WLAN_RESET_ON:
			WL_TRACE(("%s: callc customer specific GPIO to remove WLAN RESET\n",
				__FUNCTION__));
#ifdef CUSTOMER_HW
			bcm_wlan_power_on(2);
#endif /* CUSTOMER_HW */
#ifdef CUSTOMER_HW2
			//wifi_set_power(1, 0);
			//wifi_set_reset(1, 0);
#endif
			WL_ERROR(("=========== WLAN going back to live  ========\n"));
			
			ret = IW8101_wlan_power_on(RESET);
			if(ret < 0){
				printk("IW8101_wlan_power_on reset failed");
			}
		break;

		case WLAN_POWER_OFF:
			WL_TRACE(("%s: call customer specific GPIO to turn off WL_REG_ON\n",
				__FUNCTION__));
#ifdef CUSTOMER_HW
			bcm_wlan_power_off(1);
#endif /* CUSTOMER_HW */
			ret = IW8101_wlan_power_off(NORMAL);
			if(ret < 0){
				printk("IW8101_wlan_power_off failed");
			}
		break;

		case WLAN_POWER_ON:
			WL_TRACE(("%s: call customer specific GPIO to turn on WL_REG_ON\n",
				__FUNCTION__));
#ifdef CUSTOMER_HW
			bcm_wlan_power_on(1);
			/* Lets customer power to get stable */
			OSL_DELAY(200);
#endif /* CUSTOMER_HW */
			ret = IW8101_wlan_power_on(NORMAL);
			if(ret < 0){
				printk("IW8101_wlan_power_on failed");
			}
			OSL_DELAY(300);
		break;
	}
}
Beispiel #25
0
/* Customer function to control hw specific wlan gpios */
void
dhd_customer_gpio_wlan_ctrl(int onoff)
{
	switch (onoff) {
		case WLAN_RESET_OFF:
			WL_TRACE(("%s: call customer specific GPIO to insert WLAN RESET\n",
				__FUNCTION__));
#if defined(CONFIG_LGE_BCM432X_PATCH)
			//star_wifi_power(0);
			gpio_set_value(177, 0);
#endif

#ifdef CUSTOMER_HW
			bcm_wlan_power_off(2);
#endif /* CUSTOMER_HW */
#ifdef CUSTOMER_HW2
			wifi_set_power(0, 0);
#endif
			WL_ERROR(("=========== WLAN placed in RESET ========\n"));
		break;

		case WLAN_RESET_ON:
			WL_TRACE(("%s: callc customer specific GPIO to remove WLAN RESET\n",
				__FUNCTION__));
#if defined(CONFIG_LGE_BCM432X_PATCH)
			//star_wifi_power(1);
			gpio_set_value(177, 1);
			mdelay(200);
#endif
#ifdef CUSTOMER_HW
			bcm_wlan_power_on(2);
#endif /* CUSTOMER_HW */
#ifdef CUSTOMER_HW2
			wifi_set_power(1, 0);
#endif
			WL_ERROR(("=========== WLAN going back to live  ========\n"));
		break;

		case WLAN_POWER_OFF:
			WL_TRACE(("%s: call customer specific GPIO to turn off WL_REG_ON\n",
				__FUNCTION__));
#if defined(CONFIG_LGE_BCM432X_PATCH)
			//star_wifi_power(0);
			gpio_set_value(177, 0);
			
#endif
#ifdef CUSTOMER_HW
			bcm_wlan_power_off(1);
#endif /* CUSTOMER_HW */
		break;

		case WLAN_POWER_ON:
			WL_TRACE(("%s: call customer specific GPIO to turn on WL_REG_ON\n",
				__FUNCTION__));
#if defined(CONFIG_LGE_BCM432X_PATCH)

			printk("[Wi-Fi] WLAN_RESET : %d\n",	gpio_get_value(177));
			//star_wifi_power(1);
			gpio_set_value(177, 1);
			mdelay(200);
			printk("[Wi-Fi] WLAN_RESET : %d\n",	gpio_get_value(177));
#endif
#ifdef CUSTOMER_HW
			bcm_wlan_power_on(1);
#endif /* CUSTOMER_HW */
			/* Lets customer power to get stable */
			OSL_DELAY(500);
		break;
	}
}
Beispiel #26
0
/* Customer function to control hw specific wlan gpios */
void
dhd_customer_gpio_wlan_ctrl(int onoff)
{
	switch (onoff) {
		case WLAN_RESET_OFF:
			WL_TRACE(("%s: call customer specific GPIO to insert WLAN RESET\n",
				__FUNCTION__));
#if defined(CONFIG_LGE_BCM432X_PATCH)
			if (get_hw_rev() <= REV_1_2)
			{
				disable_irq(gpio_to_irq(TEGRA_GPIO_PQ5));	//by sjpark 11-03-10
				gpio_set_value(TEGRA_GPIO_PQ5, 0);
				interrupt_en_flag = 1;		//by sjpark 11-03-11
			}
			else
			{
				disable_irq(gpio_to_irq(TEGRA_GPIO_PU2));       //by sjpark 11-03-10
				gpio_set_value(TEGRA_GPIO_PU2, 0);
				interrupt_en_flag = 1;		//by sjpark 11-03-11
			}
#endif

#ifdef CUSTOMER_HW
			bcm_wlan_power_off(2);
#endif /* CUSTOMER_HW */
#ifdef CUSTOMER_HW2
			wifi_set_power(0, 0);
#endif
			WL_ERROR(("=========== WLAN placed in RESET ========\n"));
		break;

		case WLAN_RESET_ON:
			WL_TRACE(("%s: callc customer specific GPIO to remove WLAN RESET\n",
				__FUNCTION__));
#if defined(CONFIG_LGE_BCM432X_PATCH)
			if (get_hw_rev() <= REV_1_2)
				gpio_set_value(TEGRA_GPIO_PQ5, 1);
			else
				gpio_set_value(TEGRA_GPIO_PU2, 1);
			mdelay(150);
#endif
#ifdef CUSTOMER_HW
			bcm_wlan_power_on(2);
#endif /* CUSTOMER_HW */
#ifdef CUSTOMER_HW2
			wifi_set_power(1, 0);
#endif
			WL_ERROR(("=========== WLAN going back to live  ========\n"));
		break;

		case WLAN_POWER_OFF:
			WL_TRACE(("%s: call customer specific GPIO to turn off WL_REG_ON\n",
				__FUNCTION__));
#if defined(CONFIG_LGE_BCM432X_PATCH)
			if (get_hw_rev() <= REV_1_2)
			{
				gpio_set_value(TEGRA_GPIO_PQ5, 0);
				if(interrupt_en_flag == 1){
					printk("[sj-debug] POWER OFF : enable irq.\n");
					enable_irq(gpio_to_irq(TEGRA_GPIO_PQ5));	//by sjpark 11-03-10
					interrupt_en_flag = 0;		//by sjpark 11-03-11
				}
			}
			else
			{
				gpio_set_value(TEGRA_GPIO_PU2, 0);
				if(interrupt_en_flag == 1){
					printk("[sj-debug] POWER OFF : enable irq.\n");
					enable_irq(gpio_to_irq(TEGRA_GPIO_PU2));	//by sjpark 11-03-10
					interrupt_en_flag = 0;		//by sjpark 11-03-11
				}
			}

			mdelay(150);
/* always turn on 32k clock */
//			clk_disable(wifi_32k_clk);

#endif
#ifdef CUSTOMER_HW
			bcm_wlan_power_off(1);
#endif /* CUSTOMER_HW */
		break;

		case WLAN_POWER_ON:
			WL_TRACE(("%s: call customer specific GPIO to turn on WL_REG_ON\n",
				__FUNCTION__));
#if defined(CONFIG_LGE_BCM432X_PATCH)
/* Always turn on 32k clock
			wifi_32k_clk = clk_get_sys(NULL, "blink");
			if (IS_ERR(wifi_32k_clk)) {
				pr_err("%s: unable to get blink clock\n", __func__);
				//return PTR_ERR(wifi_32k_clk);
			}

			clk_enable(wifi_32k_clk);
			printk("[Wi-Fi] wifi_32k_clk is enabled\n");
*/
			if (get_hw_rev() <= REV_1_2) {
				gpio_set_value(TEGRA_GPIO_PQ5, 1);
			} else {
				gpio_set_value(TEGRA_GPIO_PU2, 1);
			}
			mdelay(150);

#endif
#ifdef CUSTOMER_HW
			bcm_wlan_power_on(1);
#endif /* CUSTOMER_HW */
			/* Lets customer power to get stable */
			OSL_DELAY(200);
		break;
	}
}
/* Customer function to control hw specific wlan gpios */
void
dhd_customer_gpio_wlan_ctrl(int onoff)
{
#if defined CUSTOMER_ALLWINNER && defined CONFIG_SW_MMC_POWER_CONTROL
    unsigned int mod_sel = mmc_pm_get_mod_type();
#endif

	switch (onoff) {
		case WLAN_RESET_OFF:
			WL_TRACE(("%s: call customer specific GPIO to insert WLAN RESET\n",
				__FUNCTION__));
/* winner's power control */
#if defined CUSTOMER_ALLWINNER && defined CONFIG_SW_MMC_POWER_CONTROL
            switch (mod_sel)
            {
                case 2: /* usi bm01a */
                    mmc_pm_gpio_ctrl("usi_bm01a_wl_rst", 0);
                    mmc_pm_gpio_ctrl("usi_bm01a_wl_regon", 0);
                    break;
                case 5: /* swb b23 */
                    mmc_pm_gpio_ctrl("swbb23_wl_shdn", 0);
                    break;
                default:
                    printk("[bcm4329]: no wifi module matched !!\n");
            }
#endif

#ifdef CUSTOMER_HW
			bcm_wlan_power_off(2);
#endif /* CUSTOMER_HW */
#ifdef CUSTOMER_HW2
			wifi_set_power(0, 0);
#endif
			WL_ERROR(("=========== WLAN placed in RESET ========\n"));
		break;

		case WLAN_RESET_ON:
			WL_TRACE(("%s: callc customer specific GPIO to remove WLAN RESET\n",
				__FUNCTION__));
/* winner's power control */
#if defined CUSTOMER_ALLWINNER && defined CONFIG_SW_MMC_POWER_CONTROL
            switch (mod_sel)
            {
                case 2: /* usi bm01a */
                    mmc_pm_gpio_ctrl("usi_bm01a_wl_regon", 1);
                    mmc_pm_gpio_ctrl("usi_bm01a_wl_rst", 1);
                    break;
                case 5: /* swb b23 */
                    mmc_pm_gpio_ctrl("swbb23_wl_shdn", 1);
                    break;
                default:
                    printk("[bcm4329]: no wifi module matched !!\n");
            }
#endif

#ifdef CUSTOMER_HW
			bcm_wlan_power_on(2);
#endif /* CUSTOMER_HW */
#ifdef CUSTOMER_HW2
			wifi_set_power(1, 0);
#endif
			WL_ERROR(("=========== WLAN going back to live  ========\n"));
			
			OSL_DELAY(10000);
		break;

		case WLAN_POWER_OFF:
			WL_TRACE(("%s: call customer specific GPIO to turn off WL_REG_ON\n",
				__FUNCTION__));
/* winner's power control */
#if defined CUSTOMER_ALLWINNER && defined CONFIG_SW_MMC_POWER_CONTROL
            switch (mod_sel)
            {
                case 2: /* usi bm01a */
                    mmc_pm_gpio_ctrl("usi_bm01a_wl_rst", 0);
                    mmc_pm_gpio_ctrl("usi_bm01a_wl_regon", 0);
                    break;
                case 5: /* swb b23 */
                    mmc_pm_gpio_ctrl("swbb23_wl_shdn", 0);
                    break;
                default:
                    printk("[bcm4329]: no wifi module matched !!\n");
            }
            sw_mmc_rescan_card(3, 0);
#endif
#ifdef CUSTOMER_HW
			bcm_wlan_power_off(1);
#endif /* CUSTOMER_HW */
		break;

		case WLAN_POWER_ON:
			WL_TRACE(("%s: call customer specific GPIO to turn on WL_REG_ON\n",
				__FUNCTION__));
/* winner's power control */
#if defined CUSTOMER_ALLWINNER && defined CONFIG_SW_MMC_POWER_CONTROL
            switch (mod_sel)
            {
                case 2: /* usi bm01a */
                    mmc_pm_gpio_ctrl("usi_bm01a_wl_regon", 1);
                    mmc_pm_gpio_ctrl("usi_bm01a_wl_rst", 1);
                    break;
                case 5: /* swb b23 */
                    mmc_pm_gpio_ctrl("swbb23_wl_shdn", 1);
                    break;
                default:
                    printk("[bcm4329]: no wifi module matched !!\n");
            }
#endif
#ifdef CUSTOMER_HW
			bcm_wlan_power_on(1);
#endif /* CUSTOMER_HW */
			/* Lets customer power to get stable */
			OSL_DELAY(200);
#if defined CUSTOMER_ALLWINNER && defined CONFIG_SW_MMC_POWER_CONTROL
            sw_mmc_rescan_card(3, 1);
#endif
		break;
	}
}
int wlc_stf_txchain_set(struct wlc_info *wlc, s32 int_val, bool force)
{
	u8 txchain = (u8) int_val;
	u8 txstreams;
	uint i;

	if (wlc->stf->txchain == txchain)
		return BCME_OK;

	if ((txchain & ~wlc->stf->hw_txchain)
	    || !(txchain & wlc->stf->hw_txchain))
		return BCME_RANGE;

	/* if nrate override is configured to be non-SISO STF mode, reject reducing txchain to 1 */
	txstreams = (u8) WLC_BITSCNT(txchain);
	if (txstreams > MAX_STREAMS_SUPPORTED)
		return BCME_RANGE;

	if (txstreams == 1) {
		for (i = 0; i < NBANDS(wlc); i++)
			if ((RSPEC_STF(wlc->bandstate[i]->rspec_override) !=
			     PHY_TXC1_MODE_SISO)
			    || (RSPEC_STF(wlc->bandstate[i]->mrspec_override) !=
				PHY_TXC1_MODE_SISO)) {
				if (!force)
					return BCME_ERROR;

				/* over-write the override rspec */
				if (RSPEC_STF(wlc->bandstate[i]->rspec_override)
				    != PHY_TXC1_MODE_SISO) {
					wlc->bandstate[i]->rspec_override = 0;
					WL_ERROR("%s(): temp sense override non-SISO rspec_override\n",
						 __func__);
				}
				if (RSPEC_STF
				    (wlc->bandstate[i]->mrspec_override) !=
				    PHY_TXC1_MODE_SISO) {
					wlc->bandstate[i]->mrspec_override = 0;
					WL_ERROR("%s(): temp sense override non-SISO mrspec_override\n",
						 __func__);
				}
			}
	}

	wlc->stf->txchain = txchain;
	wlc->stf->txstreams = txstreams;
	wlc_stf_stbc_tx_set(wlc, wlc->band->band_stf_stbc_tx);
	wlc_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
	wlc_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
	wlc->stf->txant =
	    (wlc->stf->txstreams == 1) ? ANT_TX_FORCE_0 : ANT_TX_DEF;
	_wlc_stf_phy_txant_upd(wlc);

	wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain,
			      wlc->stf->rxchain);

	for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++)
		wlc_stf_txcore_set(wlc, (u8) i, txcore_default[i]);

	return BCME_OK;
}
/* Customer function to control hw specific wlan gpios */
void
dhd_customer_gpio_wlan_ctrl(int onoff)
{
	switch (onoff) {
		case WLAN_RESET_OFF:
			WL_TRACE(("%s: call customer specific GPIO to insert WLAN RESET\n",
				__FUNCTION__));
#ifdef CUSTOMER_HW
			bcm_wlan_power_off(2);
#endif /* CUSTOMER_HW */
#if defined(CUSTOMER_HW2)
			wifi_set_power(0, WIFI_TURNOFF_DELAY);
#endif
#ifdef CUSTOMER_HW_AMLOGIC
			//extern_wifi_set_enable(0);
#endif /* CUSTOMER_HW_AMLOGIC */
			WL_ERROR(("=========== WLAN placed in RESET ========\n"));
		break;

		case WLAN_RESET_ON:
			WL_TRACE(("%s: call customer specific GPIO to remove WLAN RESET\n",
				__FUNCTION__));
#ifdef CUSTOMER_HW
			bcm_wlan_power_on(2);
			OSL_DELAY(200);
#endif /* CUSTOMER_HW */
#if defined(CUSTOMER_HW2)
			wifi_set_power(1, 200);
#endif
#ifdef CUSTOMER_HW_AMLOGIC
			extern_wifi_set_enable(0);
			mdelay(200);
			extern_wifi_set_enable(1);
			mdelay(200);
			sdio_reinit();
#endif /* CUSTOMER_HW_AMLOGIC */
			mdelay(100);
			WL_ERROR(("=========== WLAN going back to live  ========\n"));
		break;

		case WLAN_POWER_OFF:
			WL_TRACE(("%s: call customer specific GPIO to turn off WL_REG_ON\n",
				__FUNCTION__));
#ifdef CUSTOMER_HW
			bcm_wlan_power_off(1);
#endif /* CUSTOMER_HW */

#ifdef CUSTOMER_HW_AMLOGIC
			extern_wifi_set_enable(0);
#endif /* CUSTOMER_HW_AMLOGIC */
			WL_ERROR(("=========== WLAN placed in POWER OFF ========\n"));
		break;

		case WLAN_POWER_ON:
			WL_TRACE(("%s: call customer specific GPIO to turn on WL_REG_ON\n",
				__FUNCTION__));
#ifdef CUSTOMER_HW
			bcm_wlan_power_on(1);
#endif /* CUSTOMER_HW */

#ifdef CUSTOMER_HW_AMLOGIC
			extern_wifi_set_enable(0);
			mdelay(200);
			extern_wifi_set_enable(1);
			mdelay(200);
			sdio_reinit();
#endif /* CUSTOMER_HW_AMLOGIC */
			/* Lets customer power to get stable */
			OSL_DELAY(200);
			WL_ERROR(("=========== WLAN placed in POWER ON ========\n"));
		break;
	}
}
/* Customer function to control hw specific wlan gpios */
void
dhd_customer_gpio_wlan_ctrl(int onoff)
{
	switch (onoff) {
		case WLAN_RESET_OFF:
			WL_TRACE(("%s: call customer specific GPIO to insert WLAN RESET\n",
				__FUNCTION__));
#ifdef CUSTOMER_HW
			bcm_wlan_power_off(2);
#endif /* CUSTOMER_HW */
#ifdef CONFIG_MACH_MAHIMAHI
			wifi_set_power(0, 0);
#endif
			WL_ERROR(("=========== WLAN placed in RESET ========\n"));

/* LGE_CHANGE_S [[email protected]] 2009-05-14, support start/stop */
#if defined(CONFIG_LGE_BCM432X_PATCH) && defined(CONFIG_ARCH_MSM)
            if (gpio_get_value(CONFIG_BCM4330_GPIO_WL_RESET)) {
                disable_irq(gpio_to_irq(CONFIG_BCM4330_GPIO_WL_RESET));
                gpio_set_value(CONFIG_BCM4330_GPIO_WL_RESET, 0);
            }
#endif /* defined(CONFIG_LGE_BCM432X_PATCH) && defined(CONFIG_ARCH_MSM) */
/* LGE_CHANGE_E [[email protected]] 2009-05-14, support start/stop */

		break;

		case WLAN_RESET_ON:
			WL_TRACE(("%s: callc customer specific GPIO to remove WLAN RESET\n",
				__FUNCTION__));
#ifdef CUSTOMER_HW
			bcm_wlan_power_on(2);
#endif /* CUSTOMER_HW */
#ifdef CONFIG_MACH_MAHIMAHI
			wifi_set_power(1, 0);
#endif
			WL_ERROR(("=========== WLAN going back to live  ========\n"));

/* LGE_CHANGE_S [[email protected]] 2009-05-14, support start/stop */
#if defined(CONFIG_LGE_BCM432X_PATCH) && defined(CONFIG_ARCH_MSM)
            if (!gpio_get_value(CONFIG_BCM4330_GPIO_WL_RESET)) {
                gpio_set_value(CONFIG_BCM4330_GPIO_WL_RESET, 1);

                mdelay(150);

                enable_irq(gpio_to_irq(CONFIG_BCM4330_GPIO_WL_RESET));
            }
#endif /* defined(CONFIG_LGE_BCM432X_PATCH) && defined(CONFIG_ARCH_MSM) */
/* LGE_CHANGE_E [[email protected]] 2009-05-14, support start/stop */

		break;

		case WLAN_POWER_OFF:
			WL_TRACE(("%s: call customer specific GPIO to turn off WL_REG_ON\n",
				__FUNCTION__));
#ifdef CUSTOMER_HW
			bcm_wlan_power_off(1);
#endif /* CUSTOMER_HW */

/* LGE_CHANGE_S [[email protected]] 2009-03-05, for gpio set in dhd_linux */
#if defined(CONFIG_LGE_BCM432X_PATCH) && defined(CONFIG_ARCH_MSM)
			//gpio_tlmm_config(GPIO_CFG(CONFIG_BCM4330_GPIO_WL_RESET, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), GPIO_ENABLE);
			if (!gpio_get_value(CONFIG_BCM4330_GPIO_WL_RESET)) {
				gpio_set_value(CONFIG_BCM4330_GPIO_WL_RESET, 1);
				enable_irq(gpio_to_irq(CONFIG_BCM4330_GPIO_WL_RESET));
			}
			gpio_set_value(CONFIG_BCM4330_GPIO_WL_RESET, 0);
			//gpio_tlmm_config(GPIO_CFG(CONFIG_BCM4330_GPIO_WL_RESET, 0, GPIO_INPUT, GPIO_NO_PULL, GPIO_2MA), GPIO_ENABLE);
#endif /* defined(CONFIG_LGE_BCM432X_PATCH) && defined(CONFIG_ARCH_MSM) */
/* LGE_CHANGE_E [[email protected]] 2009-03-05, for gpio set in dhd_linux */

		break;

		case WLAN_POWER_ON:
			WL_TRACE(("%s: call customer specific GPIO to turn on WL_REG_ON\n",
				__FUNCTION__));
#ifdef CUSTOMER_HW
			bcm_wlan_power_on(1);
#endif /* CUSTOMER_HW */


/* LGE_CHANGE_S [[email protected]] 2009-03-05, for gpio set in dhd_linux */
#if defined(CONFIG_LGE_BCM432X_PATCH) && defined(CONFIG_ARCH_MSM)
	        gpio_set_value(CONFIG_BCM4330_GPIO_WL_RESET, 1);
#endif /* defined(CONFIG_LGE_BCM432X_PATCH) && defined(CONFIG_ARCH_MSM) */
/* LGE_CHANGE_E [[email protected]] 2009-03-05, for gpio set in dhd_linux */

			/* Lets customer power to get stable */
			OSL_DELAY(200);
		break;
	}
}