www.pudn.com > CEWifiDriverAR6000-21374.zip > htc_proto.c


//------------------------------------------------------------------------------ 
//  
//    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. 
// 
//    The software is licensed “as-is.”  
//    You must not remove this notice, or any other, from this software. 
//  
//  
//  
//    Windows CE Wifi Driver for AR-6000 
//  
//------------------------------------------------------------------------------ 
//============================================================================== 
// This file implementes a htc layer to communicate with the prototype target 
// 
// Author(s): ="Atheros" 
//============================================================================== 
 
 
#include  
#include  
#include  
#include "htc.h" 
#include "../../target/include/AR6000/AR6000_htc.h" 
 
struct htc_target { 
    void *target; 
}; 
 
#define MYHTC_MAX_BUFFERS 32 
 
typedef struct { 
    HTC_EVENT_HANDLER event_handler[8]; 
    void *param[8]; 
    void *buffer[MYHTC_MAX_BUFFERS]; 
    void *buf_cookie[MYHTC_MAX_BUFFERS]; 
    int bufindex; 
    HTC_initdone_fn_t target_init_func; 
    HTC_recvdone_fn_t target_rx_func; 
    HTC_senddone_fn_t target_sent_func; 
    struct HTC_bufinfo_s  *target_bfinfos[AR6000_MBOX_COUNT][MYHTC_MAX_BUFFERS]; 
} HTC_T; 
 
HTC_T myhtc; 
 
A_STATUS 
HTCInit(void) 
{ 
    return A_OK; 
} 
 
A_STATUS 
HTCEventReg(HTC_TARGET *target, HTC_ENDPOINT_ID endPointId, 
            HTC_EVENT_ID eventId, HTC_EVENT_HANDLER eventHandler, 
            void *param) 
{ 
    /* 
     * proto htc only supports one handler for an event for all endpoints. 
     */ 
    myhtc.event_handler[eventId] = eventHandler; 
    myhtc.param[eventId] = param; 
 
    if (eventId == HTC_TARGET_AVAILABLE) { 
        (*eventHandler)((HTC_TARGET *)&myhtc, ENDPOINT_UNUSED, 
             HTC_TARGET_AVAILABLE, NULL, NULL); 
    } 
 
    return A_OK; 
} 
 
A_STATUS 
HTCStart(HTC_TARGET *target) 
{ 
    A_STATUS status = A_OK; 
 
    if (myhtc.target_init_func != NULL) { 
        (*myhtc.target_init_func)(); 
    } else { 
        printk("HTCStart: no target init func!\n"); 
        status = A_ERROR; 
    } 
 
    return (status); 
} 
 
void 
HTCStop(HTC_TARGET *target) 
{ 
} 
 
A_STATUS 
HTCBufferSend(HTC_TARGET *target, HTC_ENDPOINT_ID endPointId, 
              A_UCHAR *buffer, A_UINT32 length, void *cookie) 
{ 
    int txEv = HTC_BUFFER_SENT; 
    int i; 
    HTC_EVENT_INFO evInfo; 
    struct HTC_bufinfo_s *htcinfo; 
 
    /* 
     * find a target buffer 
     */ 
    for (i=0; i < MYHTC_MAX_BUFFERS; i++) { 
        htcinfo = myhtc.target_bfinfos[endPointId][i]; 
        if (htcinfo != NULL) { 
            A_ASSERT(length <= htcinfo->actual_length); 
            A_MEMCPY(htcinfo->buffer, buffer, length); 
            htcinfo->actual_length = length; 
            htcinfo->next = NULL; 
            /* 
             *  Call target receive routine 
             */ 
            (*myhtc.target_rx_func)(endPointId, htcinfo); 
            evInfo.status = A_OK; 
            break; 
        } 
    } 
 
    if (i >= MYHTC_MAX_BUFFERS) { 
            printk("htc_proto: no buffer for target - dropping frame\n"); 
            evInfo.status = A_ERROR; 
    } 
 
    /* 
     * Call event handler indicating buffer was sent. 
     */ 
    evInfo.buffer       = buffer; 
    evInfo.cookie       = cookie; 
    evInfo.bufferLength = length; 
    evInfo.actualLength = length; 
 
    (*myhtc.event_handler[txEv])((HTC_TARGET *)&myhtc, endPointId, 
             HTC_BUFFER_SENT, &evInfo, myhtc.param[txEv]); 
 
    return A_OK; 
} 
 
A_STATUS 
HTCBufferReceive(HTC_TARGET *target, HTC_ENDPOINT_ID endPointId, 
                 A_UCHAR *buffer, A_UINT32 length, void *cookie) 
{ 
    int i; 
 
    for (i=0; i < MYHTC_MAX_BUFFERS; i++) { 
        if (myhtc.buffer[i] == NULL) { 
            myhtc.buffer[i] = buffer; 
            myhtc.buf_cookie[i] = cookie; 
            return A_OK; 
        } 
    } 
 
    return A_NO_MEMORY; 
} 
 
void 
HTCShutDown(HTC_TARGET *target) 
{ 
    int j, rxEv = HTC_BUFFER_RECEIVED; 
    HTC_EVENT_INFO evInfo; 
 
    /* 
     * free up queued rx buffers 
     */ 
    for (j=0; j < MYHTC_MAX_BUFFERS; j++) { 
        if (myhtc.buffer[j] != NULL) { 
            evInfo.buffer = myhtc.buffer[j]; 
            evInfo.cookie = myhtc.buf_cookie[j]; 
            myhtc.buffer[j] = NULL; 
            myhtc.buf_cookie[j] = NULL; 
 
            evInfo.bufferLength = 1500; /* XXX not correct */ 
            evInfo.actualLength = 1500; /* XXX not correct */ 
            evInfo.status       = A_ECANCELED; 
 
            (*myhtc.event_handler[rxEv])((HTC_TARGET *)&myhtc, 
                 ENDPOINT1, HTC_BUFFER_RECEIVED, &evInfo, 
                 myhtc.param[rxEv]); 
        } 
    } 
} 
 
/* 
 * Target HTC pseudo routines 
 */ 
void 
HTC_init(HTC_initdone_fn_t tinit_func, HTC_recvdone_fn_t trx_func, 
         HTC_senddone_fn_t tsent_func) 
{ 
    myhtc.target_init_func = tinit_func; 
    myhtc.target_rx_func = trx_func; 
    myhtc.target_sent_func = tsent_func; 
} 
EXPORT_SYMBOL(HTC_init); 
 
void 
HTC_mbox_bufsz_set(int mbox, int bufsz) 
{ 
} 
EXPORT_SYMBOL(HTC_mbox_bufsz_set); 
 
void 
HTC_descriptor(struct AR6000_DMA_desc_s *descriptor) 
{ 
} 
EXPORT_SYMBOL(HTC_descriptor); 
 
void 
HTC_receive(int mbox, struct HTC_bufinfo_s *bufinfo) 
{ 
    int i; 
 
    for (i = 0; i < MYHTC_MAX_BUFFERS; i++) { 
        if (myhtc.target_bfinfos[mbox][i] == NULL) { 
            /* 
             * found a slot 
             */ 
            myhtc.target_bfinfos[mbox][i] = bufinfo; 
            break; 
        } 
    } 
} 
EXPORT_SYMBOL(HTC_receive); 
 
void 
HTC_send(int mbox, struct HTC_bufinfo_s *bufinfo_orig) 
{ 
    A_UINT8 *bufPtr = NULL, *bufCookie = NULL; 
    A_UINT8 *buf; 
    int i, rxEv = HTC_BUFFER_RECEIVED; 
    HTC_EVENT_INFO evInfo; 
    struct HTC_bufinfo_s *bufinfo; 
    int totallen = HTC_HDR_SZ; 
 
    /* 
     * look for a host buffer to receive on 
     */ 
    for (i=0; i < MYHTC_MAX_BUFFERS; i++) { 
        if (myhtc.buffer[i] != NULL) { 
            bufPtr = myhtc.buffer[i]; 
            bufCookie = myhtc.buf_cookie[i]; 
            myhtc.buffer[i] = NULL; 
            myhtc.buf_cookie[i] = NULL; 
            break; 
        } 
    } 
 
    if (bufPtr == NULL) { 
        printk("htc_proto: no buffer to receive in\n"); 
        return; 
    } 
 
    buf = bufPtr; 
 
    for (bufinfo = bufinfo_orig; bufinfo != NULL; bufinfo = bufinfo->next) { 
        A_MEMCPY(buf, bufinfo->buffer, bufinfo->actual_length); 
        buf      += bufinfo->actual_length; 
        totallen += bufinfo->actual_length; 
        if (totallen > 1500) { 
            printk("htc_proto: total len max exceeded\n"); 
            return; 
        } 
    } 
 
    /* 
     * Call the event handler indicating a new buffer has been 
     * received 
     */ 
    evInfo.buffer = bufPtr; 
    evInfo.cookie = bufCookie; 
    evInfo.bufferLength = totallen;   /* XXX not correct */ 
    evInfo.actualLength = totallen; 
    evInfo.status       = A_OK; 
 
    (*myhtc.event_handler[rxEv])((HTC_TARGET *)&myhtc, mbox, 
             rxEv, &evInfo, myhtc.param[rxEv]); 
 
    /* 
     * Call target tx complete routine 
     */ 
    (*myhtc.target_sent_func)(mbox, bufinfo_orig); 
} 
 
EXPORT_SYMBOL(HTC_send);