/** * @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; }
/** * @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); }
/** * @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; }