⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 htc.c

📁 Atheros Communications AR6001 WLAN Driver for SDIO installation Read Me March 26,2007 (based on
💻 C
📖 第 1 页 / 共 2 页
字号:
//------------------------------------------------------------------------------
// <copyright file="htc.c" company="Atheros">
//    Copyright (c) 2006 Microsoft Corporation.  All rights reserved.
//    Copyright (c) 2006 Atheros Corporation.  All rights reserved.
//
//    The use and distribution terms for this software are covered by the
//    Microsoft Limited Permissive License (Ms-LPL) 
//    http://www.microsoft.com/resources/sharedsource/licensingbasics/limitedpermissivelicense.mspx 
//    which can be found in the file MS-LPL.txt at the root of this distribution.
//    By using this software in any fashion, you are agreeing to be bound by
//    the terms of this license.
//
//    You must not remove this notice, or any other, from this software.
// </copyright>
// 
// <summary>
//    Windows CE Wifi Driver for AR-6000
// </summary>
//------------------------------------------------------------------------------
//==============================================================================
// This file contains the HTC APIs that are exposed to higher layers.
//
// Author(s): ="Atheros"
//==============================================================================

#include "htc_internal.h"

/* ------ Global Variable Declarations ------- */
HTC_TARGET *AtherosTargetList[HIF_MAX_DEVICES];
HTC_GLOBAL_EVENT_TABLE AtherosEventTable;
A_MUTEX_T creditCS, counterCS, instanceCS,txCS;
A_WAITQUEUE_HEAD htcEvent;

#ifdef DEBUG
extern A_UINT32 txcreditsavailable[HTC_MAILBOX_NUM_MAX];
extern A_UINT32 txcreditsconsumed[HTC_MAILBOX_NUM_MAX];
extern A_UINT32 txcreditintrenable[HTC_MAILBOX_NUM_MAX];
extern A_UINT32 txcreditintrenableaggregate[HTC_MAILBOX_NUM_MAX];
#endif

extern int tx_attempt[HTC_MAILBOX_NUM_MAX];    /* Num of attempts to add */
extern int tx_post[HTC_MAILBOX_NUM_MAX];       /* Num of attemps succeded */
extern int tx_complete[HTC_MAILBOX_NUM_MAX];   /* Num of tx complete */

/* Initializes the HTC module */
A_STATUS
HTCInit(void)
{
    HTC_CALLBACKS htcCallbacks;
    static A_BOOL HTCInitialized = FALSE;

    HTC_DEBUG_PRINTF(ATH_LOG_TRC, "HTCInit: Enter\n");
    if (HTCInitialized) {
        HTC_DEBUG_PRINTF(ATH_LOG_TRC, "HTCInit: Exit\n");
        return A_OK;
    }

    A_MEMZERO(&AtherosEventTable, sizeof(HTC_GLOBAL_EVENT_TABLE));
    A_MEMZERO(&htcCallbacks, sizeof(HTC_CALLBACKS));
    A_INIT_WAITQUEUE_HEAD(&htcEvent);

    htcCallbacks.deviceInsertedHandler = htcTargetInsertedHandler;
    htcCallbacks.deviceRemovedHandler = htcTargetRemovedHandler;
    htcCallbacks.rwCompletionHandler = htcRWCompletionHandler;
    htcCallbacks.deviceInterruptEnabler = htcInterruptEnabler;
    htcCallbacks.deviceInterruptDisabler = htcInterruptDisabler;
    htcCallbacks.dsrHandler = htcDSRHandler;

    HIFRegisterCallbacks(&htcCallbacks);
    HTCInitialized = TRUE;

    HTC_DEBUG_PRINTF(ATH_LOG_TRC, "HTCInit: Exit\n");
    return A_OK;
}


/* Enables Dragon interrupts */
A_STATUS
HTCStart(HTC_TARGET *target) 
{
    A_STATUS status;
    A_UINT32 address;
    HIF_REQUEST request;

    HTC_DEBUG_PRINTF(ATH_LOG_TRC, "HTCStart Enter\n");

    /* make sure htc ready event is cleared, the event could be stale (already set) from previous start/stop cycles */
    A_RESET_WAIT_EVENT(&htcEvent);

    /* Unmask the host controller interrupts */
    HIFUnMaskInterrupt(target->device);

    /* Enable all the interrupts except for the dragon interrupt */
    target->table.int_status_enable = INT_STATUS_ENABLE_ERROR_SET(0x01) |
                                      INT_STATUS_ENABLE_CPU_SET(0x01) |
                                      INT_STATUS_ENABLE_COUNTER_SET(0x01) |
                                      INT_STATUS_ENABLE_MBOX_DATA_SET(0x0F);

    /* Set up the CPU Interrupt Status Register */
    target->table.cpu_int_status_enable = CPU_INT_STATUS_ENABLE_BIT_SET(0x00);

    /* Set up the Error Interrupt Status Register */
    target->table.error_status_enable = 
                                  ERROR_STATUS_ENABLE_RX_UNDERFLOW_SET(0x01) |
                                  ERROR_STATUS_ENABLE_TX_OVERFLOW_SET(0x01);

    /* Set up the Counter Interrupt Status Register */
    target->table.counter_int_status_enable = 
                                    COUNTER_INT_STATUS_ENABLE_BIT_SET(0xFF);

    /* Write to the register */
    HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, HIF_SYNCHRONOUS,
                      HIF_BYTE_BASIS, HIF_INCREMENTAL_ADDRESS);
    address = getRegAddr(INT_STATUS_ENABLE_REG, ENDPOINT_UNUSED);
    status = HIFReadWrite(target->device, address, 
                          &target->table.int_status_enable, 4, &request, NULL);
    if (status != A_OK) {
        /* Can't write it for some reason */
        HTC_DEBUG_PRINTF(ATH_LOG_ERR,
                        "Failed to enable INT_STATUS_ENABLE | CPU_INT_STATUS_ENABLE | ERROR_STATUS_ENABLE | COUNTER_INT_STATUS_ENABLE, err: %d\n", status);
        HTCStop(target);
        return status;
    }

#ifdef DEBUG
    txcreditintrenable[ENDPOINT1] += 1;
    txcreditintrenable[ENDPOINT2] += 1; 
    txcreditintrenable[ENDPOINT3] += 1; 
    txcreditintrenable[ENDPOINT4] += 1;
    txcreditintrenableaggregate[ENDPOINT1] += 1;
    txcreditintrenableaggregate[ENDPOINT2] += 1;
    txcreditintrenableaggregate[ENDPOINT3] += 1;
    txcreditintrenableaggregate[ENDPOINT4] += 1;
#endif /* DEBUG */

    /* Wait on a timed semaphore that will get signalled once the block
       size negotiation with the target has completed. Furthermore, we have
       to do it only once during the lifetime of the target detection */
    if (!target->ready) {
        HTC_DEBUG_PRINTF(ATH_LOG_INF, 
                        "Waiting for the block size negotiation to finish\n");
        A_WAIT_EVENT_INTERRUPTIBLE_TIMEOUT(&htcEvent, (target->ready == TRUE), 
                                           HTC_TARGET_RESPONSE_TIMEOUT);

        if (target->ready) {
            status = A_OK;
        } else {
            status = A_ERROR;
            HTC_DEBUG_PRINTF(ATH_LOG_ERR, 
                                "Failed to negotiate the block sizes\n");
            HTCStop(target);
        }
    }

    HTC_DEBUG_PRINTF(ATH_LOG_TRC, "HTCStart Exit\n");
    return status;
}

/* 
 * Provides an interface for the higher layer module to register for 
 * different events supported by the HTC module 
 */
A_STATUS 
HTCEventReg(HTC_TARGET *target, HTC_ENDPOINT_ID endPointId, 
            HTC_EVENT_ID eventId, HTC_EVENT_HANDLER eventHandler, 
            void *param) 
{
    /* 
     * Add the event handler against the specified event and store it in 
     * the event table 
     */
    A_STATUS status;
    HTC_ENDPOINT *endPoint;
    HTC_EVENT_INFO eventInfo;
    HTC_DATA_REQUEST_QUEUE *sendQueue, *recvQueue;

    HTC_DEBUG_PRINTF(ATH_LOG_TRC, 
                    "HTCEventReg: Enter (eventId: 0x%x, endPointId: %d)\n", 
                    eventId, endPointId);

    if (eventHandler) {
        if ((status = addToEventTable(target, endPointId, eventId, 
                                      eventHandler, param)) != A_OK)
        {
            HTC_DEBUG_PRINTF(ATH_LOG_ERR, 
                            "Could not add the event 0x%x to the event table\n", eventId);
            return status;
        }
    }

    switch(eventId) {
        case HTC_TARGET_AVAILABLE:
            if (eventHandler != NULL) {
                /* 
                 * Dispatch a Target Available event for all the targets 
                 * present. Iterate through the global list of targets but 
                 * currently we shall simply look for the first instance 
                 */
                target = AtherosTargetList[0];
                if (target != NULL) {
                    FRAME_EVENT(eventInfo, (A_UCHAR *)target->device, 
                                sizeof(HIF_DEVICE *), sizeof(HIF_DEVICE *), 
                                A_OK, NULL); 
                    dispatchEvent(target, ENDPOINT_UNUSED, eventId, &eventInfo);
                }
            } else {
                /* Initiate a shut down procedure */
            }
            break;

        case HTC_TARGET_UNAVAILABLE:
            break;

        case HTC_BUFFER_RECEIVED:
            if (eventHandler == NULL) {
                /* Flush the queue before unregistering the event handler */
                endPoint = &target->endPoint[endPointId];
                recvQueue = &endPoint->recvQueue;
                flushMboxQueue(endPoint, recvQueue, HTC_BUFFER_RECEIVED);
            }
            break;

        case HTC_SKB_RECEIVED:
            HTC_DEBUG_PRINTF(ATH_LOG_ERR, "skb not handled currently\n");
            break;

        case HTC_BUFFER_SENT:
            if (eventHandler == NULL) {
                /* Flush the queue before unregistering the event handler */
                endPoint = &target->endPoint[endPointId];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -