Ejemplo n.º 1
0
/** 
 *  @brief This function is a callback function. it is called by
 *  kernel to enter or exit power saving mode.
 *  
 *  @param pmdev   A pointer to pm_dev
 *  @param pmreq   pm_request_t
 *  @param pmdata  A pointer to pmdata
 *  @return 	   WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
 */
static int
wlan_pm_callback(struct pm_dev *pmdev, pm_request_t pmreq, void *pmdata)
{
    wlan_private *priv = &w99702_priv_data0;
    wlan_adapter *Adapter = priv->adapter;
	//struct net_device *dev = priv->wlan_dev.netdev;
	struct cyg_netdevtab_entry *dev = priv->wlan_dev.netdev;

    static BOOLEAN OS_Enable_DS = FALSE;

    diag_printf("WPRM_PM_CALLBACK: pmreq = %d.\n", pmreq);

    switch (pmreq) {
    case PM_SUSPEND:
        diag_printf("WPRM_PM_CALLBACK: enter PM_SUSPEND.\n");

#ifdef WPRM_DRV
        /* check WLAN_HOST_WAKEB */
        if (wprm_wlan_host_wakeb_is_triggered()) {
            diag_printf("exit on GPIO-1 triggered.\n");
            return WLAN_STATUS_FAILURE;
        }
#endif

        /* in associated mode */
        if (Adapter->MediaConnectStatus == WlanMediaStateConnected) {
            if ((Adapter->PSState != PS_STATE_SLEEP)
                || !Adapter->bWakeupDevRequired || (Adapter->WakeupTries != 0)
                ) {
                diag_printf("wlan_pm_callback: can't enter sleep mode\n");
                return WLAN_STATUS_FAILURE;
            } else {

                /*
                 * Detach the network interface
                 * if the network is running
                 */
                if (netif_running(dev)) {
                    netif_device_detach(dev);
                    diag_printf("netif_device_detach().\n");
                }
                /* Stop SDIO bus clock */
                stop_bus_clock_2(((mmc_card_t) ((priv->wlan_dev).card))->
                                 ctrlr);
                sbi_suspend(priv);
            }
            break;
        }

        /* in non associated mode */

        /*
         * Detach the network interface 
         * if the network is running
         */
        if (netif_running(dev))
            netif_device_detach(dev);

        /* 
         * Storing and restoring of the regs be taken care 
         * at the driver rest will be done at wlan driver
         * this makes driver independent of the card
         */
        if (Adapter->IsDeepSleep == FALSE) {
            SetDeepSleep(priv, TRUE);
            OS_Enable_DS = TRUE;
        }

        sbi_suspend(priv);

        break;

    case PM_RESUME:
        /* in associated mode */
        if (Adapter->MediaConnectStatus == WlanMediaStateConnected) {
            if (Adapter->bWakeupDevRequired == FALSE) {
                /* could never happen */
                diag_printf("wlan_pm_callback: serious error.\n");
            } else {
                /*
                 * Bring the inteface up first
                 * This case should not happen still ...
                 */
                sbi_resume(priv);

                /*
                 * Start SDIO bus clock
                 */
                sbi_set_bus_clock(priv, TRUE);
                /*
                 * Attach the network interface
                 * if the network is running
                 */
                if (netif_running(dev)) {
                    netif_device_attach(dev);
                    diag_printf("after netif_device_attach().\n");
                }
                diag_printf("After netif attach, in associated mode.\n");
            }
            break;
        }

        /* in non associated mode */

#ifdef WPRM_DRV
        /* Background scan support */
        WPRM_DRV_TRACING_PRINT();
        /* check if WLAN_HOST_WAKEB triggered, turn on SDIO_CLK */
        if (wprm_wlan_host_wakeb_is_triggered()) {      /* WLAN_HSOT_WAKEB is triggered */
            if (sbi_set_bus_clock(priv, TRUE)) {
                diag_printf(
                       "wlan_pm_callback: in PM_RESUME, wlan sdio clock turn on fail\n");
            }
            WPRM_DRV_TRACING_PRINT();
        }
#endif
        /*
         * Bring the inteface up first 
         * This case should not happen still ...
         */

        if (OS_Enable_DS == TRUE) {
#ifdef WPRM_DRV
            /* if need to wakeup FW, then trigger HOST_WLAN_WAKEB first */
            wprm_trigger_host_wlan_wakeb(1);
#endif
        }

        sbi_resume(priv);

        if (OS_Enable_DS == TRUE) {
            SetDeepSleep(priv, FALSE);
            OS_Enable_DS = FALSE;
        }

        if (netif_running(dev))
            netif_device_attach(dev);

        diag_printf("after netif attach, in NON associated mode.\n");
        break;
    }

    return WLAN_STATUS_SUCCESS;
}
Ejemplo n.º 2
0
/**
 *  @brief This function processes received packet and forwards it
 *  to kernel/upper layer
 *  
 *  @param priv    A pointer to wlan_private
 *  @param skb     A pointer to skb which includes the received packet
 *  @return 	   WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
 */
int
ProcessRxedPacket(wlan_private * priv, struct sk_buff *skb)
{
#ifdef WPRM_DRV
    wlan_adapter *Adapter = priv->adapter;
#endif
    int ret = WLAN_STATUS_SUCCESS;

    RxPacketHdr_t *pRxPkt;
    RxPD *pRxPD;

    int hdrChop;
    EthII_Hdr_t *pEthHdr;
    u32 u32SkbLen = skb->len;

    const u8 rfc1042_eth_hdr[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };

    ENTER();

    pRxPkt = (RxPacketHdr_t *) skb->data;
    pRxPD = &pRxPkt->rx_pd;

    DBG_HEXDUMP(DAT_D, "Rx", skb->data, MIN(skb->len, MAX_DATA_DUMP_LEN));

    if (skb->len < (ETH_HLEN + 8 + sizeof(RxPD))) {
        PRINTM(ERROR, "RX Error: FRAME RECEIVED WITH BAD LENGTH\n");
        priv->stats.rx_length_errors++;
        ret = WLAN_STATUS_SUCCESS;
        kfree_skb(skb);
        goto done;
    }

    PRINTM(INFO, "RX Data: skb->len - sizeof(RxPd) = %d - %d = %d\n",
           skb->len, sizeof(RxPD), skb->len - sizeof(RxPD));

    HEXDUMP("RX Data: Dest", pRxPkt->eth803_hdr.dest_addr,
            sizeof(pRxPkt->eth803_hdr.dest_addr));
    HEXDUMP("RX Data: Src", pRxPkt->eth803_hdr.src_addr,
            sizeof(pRxPkt->eth803_hdr.src_addr));

    if (memcmp(&pRxPkt->rfc1042_hdr,
               rfc1042_eth_hdr, sizeof(rfc1042_eth_hdr)) == 0) {
        /* 
         *  Replace the 803 header and rfc1042 header (llc/snap) with an 
         *    EthernetII header, keep the src/dst and snap_type (ethertype)
         *
         *  The firmware only passes up SNAP frames converting
         *    all RX Data from 802.11 to 802.2/LLC/SNAP frames.
         *
         *  To create the Ethernet II, just move the src, dst address right
         *    before the snap_type.
         */
        pEthHdr = (EthII_Hdr_t *)
            ((u8 *) & pRxPkt->eth803_hdr
             + sizeof(pRxPkt->eth803_hdr) + sizeof(pRxPkt->rfc1042_hdr)
             - sizeof(pRxPkt->eth803_hdr.dest_addr)
             - sizeof(pRxPkt->eth803_hdr.src_addr)
             - sizeof(pRxPkt->rfc1042_hdr.snap_type));

        memcpy(pEthHdr->src_addr, pRxPkt->eth803_hdr.src_addr,
               sizeof(pEthHdr->src_addr));
        memcpy(pEthHdr->dest_addr, pRxPkt->eth803_hdr.dest_addr,
               sizeof(pEthHdr->dest_addr));

        /* Chop off the RxPD + the excess memory from the 802.2/llc/snap header
         *   that was removed 
         */
        hdrChop = (u8 *) pEthHdr - (u8 *) pRxPkt;
    } else {
        HEXDUMP("RX Data: LLC/SNAP",
                (u8 *) & pRxPkt->rfc1042_hdr, sizeof(pRxPkt->rfc1042_hdr));

        /* Chop off the RxPD */
        hdrChop = (u8 *) & pRxPkt->eth803_hdr - (u8 *) pRxPkt;
    }

    /* Chop off the leading header bytes so the skb points to the start of 
     *   either the reconstructed EthII frame or the 802.2/llc/snap frame
     */
    skb_pull(skb, hdrChop);

    u32SkbLen = skb->len;
    wlan_compute_rssi(priv, pRxPD);

    if (os_upload_rx_packet(priv, skb)) {
        PRINTM(ERROR, "RX Error: os_upload_rx_packet" " returns failure\n");
        ret = WLAN_STATUS_FAILURE;
        goto done;
    }
    priv->stats.rx_bytes += u32SkbLen;
    priv->stats.rx_packets++;

    PRINTM(DATA, "Data => kernel\n");
#ifdef WPRM_DRV
    WPRM_DRV_TRACING_PRINT();
    /* increase traffic meter rx counter 
       and call measurement function to see 
       if we need to change FW power mode. */
    wprm_rx_packet_cnt++;
    wprm_traffic_measurement(priv, Adapter, FALSE);
#endif
    ret = WLAN_STATUS_SUCCESS;
  done:
    LEAVE();

    return (ret);
}
Ejemplo n.º 3
0
/**
 *  @brief This function initializes the adapter structure
 *  and set default value to the member of adapter.
 *  
 *  @param priv    A pointer to wlan_private structure
 *  @return 	   n/a
 */
static void
wlan_init_adapter(wlan_private * priv)
{
    wlan_adapter *Adapter = priv->adapter;
    int i;

    Adapter->ScanProbes = 0;

    Adapter->bcn_avg_factor = DEFAULT_BCN_AVG_FACTOR;
    Adapter->data_avg_factor = DEFAULT_DATA_AVG_FACTOR;

    /* ATIM params */
    Adapter->AtimWindow = 0;
    Adapter->ATIMEnabled = FALSE;

    Adapter->MediaConnectStatus = WlanMediaStateDisconnected;
#ifdef WPRM_DRV
    WPRM_DRV_TRACING_PRINT();
    /* Stop Traffic meter */
    wprm_traffic_meter_exit(priv);
#endif
    Adapter->LinkSpeed = MRVDRV_LINK_SPEED_1mbps;
    memset(Adapter->CurrentAddr, 0xff, MRVDRV_ETH_ADDR_LEN);

    /* Status variables */
    Adapter->HardwareStatus = WlanHardwareStatusInitializing;

    /* scan type */
    Adapter->ScanType = HostCmd_SCAN_TYPE_ACTIVE;

    /* scan mode */
    Adapter->ScanMode = HostCmd_BSS_TYPE_ANY;

    /* scan time */
    Adapter->SpecificScanTime = MRVDRV_SPECIFIC_SCAN_CHAN_TIME;
    Adapter->ActiveScanTime = MRVDRV_ACTIVE_SCAN_CHAN_TIME;
    Adapter->PassiveScanTime = MRVDRV_PASSIVE_SCAN_CHAN_TIME;

    /* 802.11 specific */
    Adapter->SecInfo.WEPStatus = Wlan802_11WEPDisabled;
    for (i = 0; i < sizeof(Adapter->WepKey) / sizeof(Adapter->WepKey[0]); i++)
        memset(&Adapter->WepKey[i], 0, sizeof(MRVL_WEP_KEY));
    Adapter->CurrentWepKeyIndex = 0;
    Adapter->SecInfo.AuthenticationMode = Wlan802_11AuthModeOpen;
    Adapter->SecInfo.EncryptionMode = CIPHER_NONE;
    Adapter->AdhocAESEnabled = FALSE;
    Adapter->InfrastructureMode = Wlan802_11Infrastructure;

    Adapter->NumInScanTable = 0;
    Adapter->pAttemptedBSSDesc = NULL;
#ifdef REASSOCIATION
    OS_INIT_SEMAPHORE(&Adapter->ReassocSem);
#endif
    Adapter->pBeaconBufEnd = Adapter->beaconBuffer;

    Adapter->Prescan = CMD_ENABLED;
    Adapter->HisRegCpy |= HIS_TxDnLdRdy;

    memset(&Adapter->CurBssParams, 0, sizeof(Adapter->CurBssParams));

    /* PnP and power profile */
    Adapter->SurpriseRemoved = FALSE;

    Adapter->CurrentPacketFilter =
        HostCmd_ACT_MAC_RX_ON | HostCmd_ACT_MAC_TX_ON;

    Adapter->RadioOn = RADIO_ON;
#ifdef REASSOCIATION
    Adapter->Reassoc_on = TRUE;
#endif /* REASSOCIATION */
    Adapter->TxAntenna = RF_ANTENNA_2;
    Adapter->RxAntenna = RF_ANTENNA_AUTO;

    Adapter->HWRateDropMode = HW_TABLE_RATE_DROP;
    Adapter->Is_DataRate_Auto = TRUE;
    Adapter->BeaconPeriod = MRVDRV_BEACON_INTERVAL;

    // set default value of capInfo.
#define SHORT_PREAMBLE_ALLOWED		1
    memset(&Adapter->capInfo, 0, sizeof(Adapter->capInfo));
    Adapter->capInfo.ShortPreamble = SHORT_PREAMBLE_ALLOWED;

    Adapter->AdhocChannel = DEFAULT_AD_HOC_CHANNEL;

    Adapter->PSMode = Wlan802_11PowerModeCAM;
    Adapter->MultipleDtim = MRVDRV_DEFAULT_MULTIPLE_DTIM;

    Adapter->ListenInterval = MRVDRV_DEFAULT_LISTEN_INTERVAL;

    Adapter->PSState = PS_STATE_FULL_POWER;
#ifdef MOTO_DBG
    PRINTM(INFO, "PSState set to PS_STATE_AWAKE - KO for DSM\n");
#endif
    Adapter->NeedToWakeup = FALSE;
    Adapter->LocalListenInterval = 0;   /* default value in firmware will be used */
    Adapter->fwWakeupMethod = WAKEUP_FW_UNCHANGED;

    Adapter->IsDeepSleep = FALSE;

    Adapter->bWakeupDevRequired = FALSE;
#ifdef MOTO_DBG
    PRINTM(INFO, "bWakeupDevRequired set to FALSE - KO for DSM\n");
#endif
    Adapter->bHostSleepConfigured = FALSE;
    Adapter->WakeupTries = 0;
#ifdef MOTO_DBG
    PRINTM(INFO, "WakeupTries set to 0 - OK for DSM\n");
#endif
    Adapter->HSCfg.conditions = HOST_SLEEP_CFG_CANCEL;
    Adapter->HSCfg.gpio = 0;
    Adapter->HSCfg.gap = 0;

    Adapter->DataRate = 0;      // Initially indicate the rate as auto 

    Adapter->adhoc_grate_enabled = FALSE;

    Adapter->IntCounter = Adapter->IntCounterSaved = 0;
    memset(&Adapter->wmm, 0, sizeof(WMM_DESC));
    for (i = 0; i < MAX_AC_QUEUES; i++)
        INIT_LIST_HEAD((struct list_head *) &Adapter->wmm.TxSkbQ[i]);
    INIT_LIST_HEAD((struct list_head *) &Adapter->RxSkbQ);
    Adapter->gen_null_pkg = TRUE;       /*Enable NULL Pkg generation */

    INIT_LIST_HEAD((struct list_head *) &Adapter->TxSkbQ);
    Adapter->TxSkbNum = 0;

    Adapter->fwstate = FW_STATE_NREADY;
    init_waitqueue_head(&Adapter->cmd_EncKey);

    Adapter->EncryptionStatus = Wlan802_11WEPDisabled;

    spin_lock_init(&Adapter->CurrentTxLock);

    Adapter->CurrentTxSkb = NULL;
    Adapter->PktTxCtrl = 0;

    return;
}