uboot/arch/arm/cpu/ixp/npe/IxEthDBWiFi.c
<<
>>
Prefs
   1/**
   2 * @file IxEthDBAPI.c
   3 *
   4 * @brief Implementation of the public API
   5 * 
   6 * @par
   7 * IXP400 SW Release version 2.0
   8 * 
   9 * -- Copyright Notice --
  10 * 
  11 * @par
  12 * Copyright 2001-2005, Intel Corporation.
  13 * All rights reserved.
  14 * 
  15 * @par
  16 * Redistribution and use in source and binary forms, with or without
  17 * modification, are permitted provided that the following conditions
  18 * are met:
  19 * 1. Redistributions of source code must retain the above copyright
  20 *    notice, this list of conditions and the following disclaimer.
  21 * 2. Redistributions in binary form must reproduce the above copyright
  22 *    notice, this list of conditions and the following disclaimer in the
  23 *    documentation and/or other materials provided with the distribution.
  24 * 3. Neither the name of the Intel Corporation nor the names of its contributors
  25 *    may be used to endorse or promote products derived from this software
  26 *    without specific prior written permission.
  27 * 
  28 * @par
  29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
  30 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  32 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
  33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  39 * SUCH DAMAGE.
  40 * 
  41 * @par
  42 * -- End of Copyright Notice --
  43 */
  44
  45#include "IxEthDB_p.h"
  46
  47/* forward prototypes */
  48IX_ETH_DB_PUBLIC
  49MacTreeNode *ixEthDBGatewaySelect(MacTreeNode *stations);
  50
  51/**
  52 * @brief sets the BBSID value for the WiFi header conversion feature
  53 *
  54 * @param portID ID of the port
  55 * @param bbsid pointer to the 6-byte BBSID value
  56 *
  57 * Note that this function is documented in the main component
  58 * header file, IxEthDB.h.
  59 *
  60 * @return IX_ETH_DB_SUCCESS if the operation completed successfully
  61 * or an appropriate error message otherwise
  62 */
  63IX_ETH_DB_PUBLIC
  64IxEthDBStatus ixEthDBWiFiBBSIDSet(IxEthDBPortId portID, IxEthDBMacAddr *bbsid)
  65{
  66    IxNpeMhMessage message;
  67    IX_STATUS result;
  68    
  69    IX_ETH_DB_CHECK_PORT(portID);
  70    
  71    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
  72    
  73    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
  74 
  75    IX_ETH_DB_CHECK_REFERENCE(bbsid);
  76    
  77    memcpy(ixEthDBPortInfo[portID].bbsid, bbsid, sizeof (IxEthDBMacAddr));
  78
  79    FILL_SETBBSID_MSG(message, portID, bbsid);
  80
  81    IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
  82    
  83    return result;
  84}
  85
  86/**
  87 * @brief updates the Frame Control and Duration/ID WiFi header
  88 * conversion parameters in an NPE
  89 *
  90 * @param portID ID of the port
  91 *
  92 * This function will send a message to the NPE updating the 
  93 * frame conversion parameters for 802.3 => 802.11 header conversion.
  94 *
  95 * @return IX_ETH_DB_SUCCESS if the operation completed successfully
  96 * or IX_ETH_DB_FAIL otherwise
  97 *
  98 * @internal
  99 */
 100IX_ETH_DB_PRIVATE
 101IxEthDBStatus ixEthDBWiFiFrameControlDurationIDUpdate(IxEthDBPortId portID)
 102{
 103    IxNpeMhMessage message;
 104    IX_STATUS result;
 105
 106    FILL_SETFRAMECONTROLDURATIONID(message, portID, ixEthDBPortInfo[portID].frameControlDurationID);
 107    
 108    IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
 109    
 110    return result;
 111}
 112
 113/**
 114 * @brief sets the Duration/ID WiFi frame header conversion parameter
 115 *
 116 * @param portID ID of the port
 117 * @param durationID 16-bit value containing the new Duration/ID parameter
 118 *
 119 * Note that this function is documented in the main component
 120 * header file, IxEthDB.h.
 121 *
 122 * @return IX_ETH_DB_SUCCESS if the operation completed successfully
 123 * or an appropriate error message otherwise
 124 */
 125IX_ETH_DB_PUBLIC
 126IxEthDBStatus ixEthDBWiFiDurationIDSet(IxEthDBPortId portID, UINT16 durationID)
 127{
 128    IX_ETH_DB_CHECK_PORT(portID);
 129    
 130    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
 131    
 132    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
 133
 134    ixEthDBPortInfo[portID].frameControlDurationID = (ixEthDBPortInfo[portID].frameControlDurationID & 0xFFFF0000) | durationID;
 135    
 136    return ixEthDBWiFiFrameControlDurationIDUpdate(portID);
 137}
 138
 139/**
 140 * @brief sets the Frame Control WiFi frame header conversion parameter
 141 *
 142 * @param portID ID of the port
 143 * @param durationID 16-bit value containing the new Frame Control parameter
 144 *
 145 * Note that this function is documented in the main component
 146 * header file, IxEthDB.h.
 147 *
 148 * @return IX_ETH_DB_SUCCESS if the operation completed successfully
 149 * or an appropriate error message otherwise
 150 */
 151IX_ETH_DB_PUBLIC
 152IxEthDBStatus ixEthDBWiFiFrameControlSet(IxEthDBPortId portID, UINT16 frameControl)
 153{
 154    IX_ETH_DB_CHECK_PORT(portID);
 155    
 156    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
 157    
 158    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
 159
 160    ixEthDBPortInfo[portID].frameControlDurationID = (ixEthDBPortInfo[portID].frameControlDurationID & 0xFFFF) | (frameControl << 16); 
 161    
 162    return ixEthDBWiFiFrameControlDurationIDUpdate(portID);
 163}
 164
 165/**
 166 * @brief removes a WiFi header conversion record
 167 *
 168 * @param portID ID of the port
 169 * @param macAddr MAC address of the record to remove
 170 *
 171 * Note that this function is documented in the main
 172 * component header file, IxEthDB.h.
 173 *
 174 * @return IX_ETH_DB_SUCCESS if the operation completed
 175 * successfully or an appropriate error message otherwise
 176 */
 177IX_ETH_DB_PUBLIC
 178IxEthDBStatus ixEthDBWiFiEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
 179{
 180    MacDescriptor recordTemplate;
 181    
 182    IX_ETH_DB_CHECK_PORT(portID);
 183    
 184    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
 185    
 186    IX_ETH_DB_CHECK_REFERENCE(macAddr);
 187    
 188    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
 189    
 190    memcpy(recordTemplate.macAddress, macAddr, sizeof (IxEthDBMacAddr));
 191    
 192    recordTemplate.type   = IX_ETH_DB_WIFI_RECORD;
 193    recordTemplate.portID = portID;
 194    
 195    return ixEthDBRemove(&recordTemplate, NULL);
 196}
 197
 198/**
 199 * @brief adds a WiFi header conversion record
 200 *
 201 * @param portID ID of the port
 202 * @param macAddr MAC address of the record to add
 203 * @param gatewayMacAddr address of the gateway (or
 204 * NULL if this is a station record)
 205 *
 206 * This function adds a record of type AP_TO_AP (gateway is not NULL)
 207 * or AP_TO_STA (gateway is NULL) in the main database as a 
 208 * WiFi header conversion record.
 209 *
 210 * @return IX_ETH_DB_SUCCESS if the operation completed
 211 * successfully or an appropriate error message otherwise
 212 *
 213 * @internal
 214 */
 215IX_ETH_DB_PRIVATE
 216IxEthDBStatus ixEthDBWiFiEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr, IxEthDBMacAddr *gatewayMacAddr)
 217{
 218    MacDescriptor recordTemplate;
 219
 220    IX_ETH_DB_CHECK_PORT(portID);
 221
 222    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
 223
 224    IX_ETH_DB_CHECK_REFERENCE(macAddr);
 225    
 226    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
 227
 228    memcpy(recordTemplate.macAddress, macAddr, sizeof (IxEthDBMacAddr));
 229    
 230    recordTemplate.type   = IX_ETH_DB_WIFI_RECORD;
 231    recordTemplate.portID = portID;
 232    
 233    if (gatewayMacAddr != NULL)
 234    {
 235        memcpy(recordTemplate.recordData.wifiData.gwMacAddress, gatewayMacAddr, sizeof (IxEthDBMacAddr));
 236        
 237        recordTemplate.recordData.wifiData.type = IX_ETH_DB_WIFI_AP_TO_AP;
 238    }
 239    else
 240    {
 241        memset(recordTemplate.recordData.wifiData.gwMacAddress, 0, sizeof (IxEthDBMacAddr));
 242
 243        recordTemplate.recordData.wifiData.type = IX_ETH_DB_WIFI_AP_TO_STA;
 244    }
 245    
 246    return ixEthDBAdd(&recordTemplate, NULL);
 247}
 248
 249/**
 250 * @brief adds a WiFi header conversion record
 251 *
 252 * @param portID ID of the port
 253 * @param macAddr MAC address of the record to add
 254 * @param gatewayMacAddr address of the gateway 
 255 *
 256 * This function adds a record of type AP_TO_AP
 257 * in the main database as a WiFi header conversion record.
 258 *
 259 * This is simply a wrapper over @ref ixEthDBWiFiEntryAdd().
 260 *
 261 * Note that this function is documented in the main
 262 * component header file, IxEthDB.h.
 263 *
 264 * @return IX_ETH_DB_SUCCESS if the operation completed
 265 * successfully or an appropriate error message otherwise
 266 */
 267IX_ETH_DB_PUBLIC
 268IxEthDBStatus ixEthDBWiFiAccessPointEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr, IxEthDBMacAddr *gatewayMacAddr)
 269{
 270    IX_ETH_DB_CHECK_REFERENCE(gatewayMacAddr);
 271
 272    return ixEthDBWiFiEntryAdd(portID, macAddr, gatewayMacAddr);
 273}
 274
 275/**
 276 * @brief adds a WiFi header conversion record
 277 *
 278 * @param portID ID of the port
 279 * @param macAddr MAC address of the record to add
 280 *
 281 * This function adds a record of type AP_TO_STA
 282 * in the main database as a WiFi header conversion record.
 283 *
 284 * This is simply a wrapper over @ref ixEthDBWiFiEntryAdd().
 285 *
 286 * Note that this function is documented in the main
 287 * component header file, IxEthDB.h.
 288 *
 289 * @return IX_ETH_DB_SUCCESS if the operation completed
 290 * successfully or an appropriate error message otherwise
 291 */
 292IX_ETH_DB_PUBLIC
 293IxEthDBStatus ixEthDBWiFiStationEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
 294{
 295    return ixEthDBWiFiEntryAdd(portID, macAddr, NULL);
 296}
 297
 298/**
 299 * @brief selects a set of gateways from a tree of 
 300 * WiFi header conversion records
 301 *
 302 * @param stations binary tree containing pointers to WiFi header
 303 * conversion records
 304 *
 305 * This function browses through the input binary tree, identifies
 306 * records of type AP_TO_AP, clones these records and appends them
 307 * to a vine (a single right-branch binary tree) which is returned
 308 * as result. A maximum of MAX_GW_SIZE entries containing gateways
 309 * will be cloned from the original tree.
 310 *
 311 * @return vine (linear binary tree) containing record
 312 * clones of AP_TO_AP type, which have a gateway field
 313 *
 314 * @internal
 315 */
 316IX_ETH_DB_PUBLIC
 317MacTreeNode *ixEthDBGatewaySelect(MacTreeNode *stations)
 318{
 319    MacTreeNodeStack *stack;
 320    MacTreeNode *gateways, *insertionPlace;
 321    UINT32 gwIndex = 1; /* skip the empty root */
 322    
 323    if (stations == NULL)
 324    {
 325        return NULL;
 326    }
 327
 328    stack = ixOsalCacheDmaMalloc(sizeof (MacTreeNodeStack));
 329
 330    if (stack == NULL)
 331    {
 332        ERROR_LOG("DB: (WiFi) failed to allocate the node stack for gateway tree linearization, out of memory?\n");
 333        return NULL;
 334    }
 335    
 336    /* initialize root node */
 337    gateways = insertionPlace = NULL;
 338        
 339    /* start browsing the station tree */
 340    NODE_STACK_INIT(stack);
 341    
 342    /* initialize stack by pushing the tree root at offset 0 */
 343    NODE_STACK_PUSH(stack, stations, 0);
 344    
 345    while (NODE_STACK_NONEMPTY(stack))
 346    {
 347        MacTreeNode *node;
 348        UINT32 offset;
 349       
 350        NODE_STACK_POP(stack, node, offset);
 351
 352        /* we can store maximum 31 (32 total, 1 empty root) entries in the gateway tree */
 353        if (offset > (MAX_GW_SIZE - 1)) break;
 354        
 355        /* check if this record has a gateway address */
 356        if (node->descriptor != NULL && node->descriptor->recordData.wifiData.type == IX_ETH_DB_WIFI_AP_TO_AP)
 357        {
 358            /* found a record, create an insertion place */
 359            if (insertionPlace != NULL)
 360            {
 361                insertionPlace->right = ixEthDBAllocMacTreeNode();
 362                insertionPlace        = insertionPlace->right;
 363            }
 364            else
 365            {
 366                gateways       = ixEthDBAllocMacTreeNode();
 367                insertionPlace = gateways;
 368            }
 369
 370            if (insertionPlace == NULL)
 371            {
 372                /* no nodes left, bail out with what we have */
 373                ixOsalCacheDmaFree(stack);
 374                return gateways;
 375            }
 376            
 377            /* clone the original record for the gateway tree */
 378            insertionPlace->descriptor = ixEthDBCloneMacDescriptor(node->descriptor);
 379            
 380            /* insert and update the offset in the original record */
 381            node->descriptor->recordData.wifiData.gwAddressIndex = gwIndex++;
 382        }
 383        
 384        /* browse the tree */
 385        if (node->left != NULL)
 386        {
 387            NODE_STACK_PUSH(stack, node->left, LEFT_CHILD_OFFSET(offset));
 388        }
 389
 390        if (node->right != NULL)
 391        {
 392            NODE_STACK_PUSH(stack, node->right, RIGHT_CHILD_OFFSET(offset));
 393        }
 394    }
 395    
 396    ixOsalCacheDmaFree(stack);
 397    return gateways;    
 398}
 399
 400/**
 401 * @brief downloads the WiFi header conversion table to an NPE
 402 *
 403 * @param portID ID of the port
 404 *
 405 * This function prepares the WiFi header conversion tables and
 406 * downloads them to the specified NPE port.
 407 *
 408 * The header conversion tables consist in the main table of
 409 * addresses and the secondary table of gateways. AP_TO_AP records
 410 * from the first table contain index fields into the second table
 411 * for gateway selection.
 412 *
 413 * Note that this function is documented in the main component
 414 * header file, IxEthDB.h.
 415 *
 416 * @return IX_ETH_DB_SUCCESS if the operation completed successfully
 417 * or an appropriate error message otherwise
 418 */
 419IX_ETH_DB_PUBLIC
 420IxEthDBStatus ixEthDBWiFiConversionTableDownload(IxEthDBPortId portID)
 421{
 422    IxEthDBPortMap query;
 423    MacTreeNode *stations = NULL, *gateways = NULL, *gateway = NULL;
 424    IxNpeMhMessage message;
 425    PortInfo *portInfo;
 426    IX_STATUS result;
 427
 428    IX_ETH_DB_CHECK_PORT(portID);
 429
 430    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
 431    
 432    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
 433
 434    portInfo = &ixEthDBPortInfo[portID];
 435   
 436    SET_DEPENDENCY_MAP(query, portID);
 437    
 438    ixEthDBUpdateLock();
 439
 440    stations = ixEthDBQuery(NULL, query, IX_ETH_DB_WIFI_RECORD, MAX_ELT_SIZE);
 441    gateways = ixEthDBGatewaySelect(stations);
 442    
 443    /* clean up gw area */
 444    memset((void *) portInfo->updateMethod.npeGwUpdateZone, FULL_GW_BYTE_SIZE, 0);
 445
 446    /* write all gateways */
 447    gateway = gateways;
 448
 449    while (gateway != NULL)
 450    {
 451        ixEthDBNPEGatewayNodeWrite((void *) (((UINT32) portInfo->updateMethod.npeGwUpdateZone) 
 452            + gateway->descriptor->recordData.wifiData.gwAddressIndex * ELT_ENTRY_SIZE), 
 453            gateway);
 454
 455        gateway = gateway->right;
 456    }
 457
 458    /* free the gateway tree */
 459    if (gateways != NULL)
 460    {
 461        ixEthDBFreeMacTreeNode(gateways);
 462    }
 463
 464    FILL_SETAPMACTABLE_MSG(message, 
 465        IX_OSAL_MMU_VIRT_TO_PHYS(portInfo->updateMethod.npeGwUpdateZone));
 466
 467    IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
 468
 469    if (result == IX_SUCCESS)
 470    {
 471        /* update the main tree (the stations tree) */
 472        portInfo->updateMethod.searchTree = stations;
 473        
 474        result = ixEthDBNPEUpdateHandler(portID, IX_ETH_DB_WIFI_RECORD);
 475    }
 476
 477    ixEthDBUpdateUnlock();
 478
 479    return result;
 480}
 481