Ejemplo n.º 1
0
/**
 @brief    This helper function is used to clean up the pending 
           messages in the transport queue

 @param wctsHandlehandle:  transport handle

 @see
 @return   0 for success
*/
wpt_uint32
WCTS_ClearPendingQueue
(
   WCTS_HandleType      wctsHandle
)
{
   WCTS_ControlBlockType* pWCTSCb = (WCTS_ControlBlockType*) wctsHandle;
   wpt_list_node*      pNode = NULL;
   WCTS_BufferType*    pBufferQueue = NULL;
   void*               pBuffer = NULL;

   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   if ((NULL == pWCTSCb) || (WCTS_CB_MAGIC != pWCTSCb->wctsMagic)) {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "WCTS_ClearPendingQueue: Invalid parameters received.");
      return eWLAN_PAL_STATUS_E_INVAL;
   }

   /*Free the buffers in the pending queue.*/
   while (eWLAN_PAL_STATUS_SUCCESS ==
          wpal_list_remove_front(&pWCTSCb->wctsPendingQueue, &pNode)) {
      pBufferQueue = container_of(pNode, WCTS_BufferType, node);
      pBuffer = pBufferQueue->pBuffer;
      wpalMemoryFree(pBuffer);
      wpalMemoryFree(pBufferQueue);
   }
   return eWLAN_PAL_STATUS_SUCCESS;

}/*WCTS_ClearPendingQueue*/
Ejemplo n.º 2
0
static void
WCTS_PALWriteCallback
(
   WCTS_ControlBlockType*  pWCTSCb
)
{
   wpt_list_node*      pNode;
   WCTS_BufferType*    pBufferQueue;
   void*               pBuffer;
   int                 len;
   int                 available;
   int                 written;

   

   if ((NULL == pWCTSCb) || (WCTS_CB_MAGIC != pWCTSCb->wctsMagic)) {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "WCTS_PALWriteCallback: Invalid parameter received.");
      return;
   }

   
   if (WCTS_STATE_DEFERRED != pWCTSCb->wctsState) {
      return;
   }

   while (eWLAN_PAL_STATUS_SUCCESS ==
          wpal_list_peek_front(&pWCTSCb->wctsPendingQueue, &pNode)) {
      pBufferQueue = container_of(pNode, WCTS_BufferType, node);
      pBuffer = pBufferQueue->pBuffer;
      len = pBufferQueue->bufferSize;

      available = smd_write_avail(pWCTSCb->wctsChannel);
      if (available < len) {
         
         return;
      }

      wpal_list_remove_front(&pWCTSCb->wctsPendingQueue, &pNode);


      written = smd_write(pWCTSCb->wctsChannel, pBuffer, len);
      if (written != len) {
         
         WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                    "WCTS_PALWriteCallback: channel write failure");

      }

      
      wpalMemoryFree(pBuffer);
      wpalMemoryFree(pBufferQueue);

   }

   pWCTSCb->wctsState = WCTS_STATE_OPEN;
   smd_disable_read_intr(pWCTSCb->wctsChannel);

} 
Ejemplo n.º 3
0
/**
 @brief    This function is used by the DAL Core to close the
           Control Transport when its services are no longer
           needed. Full close notification will be receive
           asynchronously on the notification callback
           registered on Open


 @param wctsHandlehandle:  received upon open

 @see
 @return   0 for success
*/
wpt_uint32
WCTS_CloseTransport
(
   WCTS_HandleType      wctsHandle
)
{
   WCTS_ControlBlockType* pWCTSCb = (WCTS_ControlBlockType*) wctsHandle;
   wpt_list_node*      pNode = NULL;
   WCTS_BufferType*    pBufferQueue = NULL;
   void*               pBuffer = NULL;
   wpt_status          status;
   int                 smdstatus;

   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   if ((NULL == pWCTSCb) || (WCTS_CB_MAGIC != pWCTSCb->wctsMagic)) {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "WCTS_CloseTransport: Invalid parameters received.");
      return eWLAN_PAL_STATUS_E_INVAL;
   }

#ifdef FEATURE_R33D
   /* Not actually close port, just pretend */
   /* notified registered client that the channel is closed */
   pWCTSCb->wctsState = WCTS_STATE_CLOSED;
   pWCTSCb->wctsNotifyCB((WCTS_HandleType)pWCTSCb,
                         WCTS_EVENT_CLOSE,
                         pWCTSCb->wctsNotifyCBData);

   printk(KERN_ERR "R33D Not need to close");
   return eWLAN_PAL_STATUS_SUCCESS;
#endif /* FEATURE_R33D */

   /*Free the buffers in the pending queue.*/
   while (eWLAN_PAL_STATUS_SUCCESS ==
          wpal_list_remove_front(&pWCTSCb->wctsPendingQueue, &pNode)) {
      pBufferQueue = container_of(pNode, WCTS_BufferType, node);
      pBuffer = pBufferQueue->pBuffer;
      wpalMemoryFree(pBuffer);
      wpalMemoryFree(pBufferQueue);
   }

   /* Reset the state */
   pWCTSCb->wctsState = WCTS_STATE_CLOSED;

   wpalEventReset(&pWCTSCb->wctsEvent);
   smdstatus = smd_close(pWCTSCb->wctsChannel);
   if (0 != smdstatus) {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "%s: smd_close failed with status %d",
                 __func__, smdstatus);
      /* SMD did not successfully close the channel, therefore we
         won't receive an asynchronous close notification so don't
         bother to wait for an event that won't come */

   } else {
      /* close command was sent -- wait for the callback to complete */
      status = wpalEventWait(&pWCTSCb->wctsEvent, WCTS_SMD_CLOSE_TIMEOUT);
      if (eWLAN_PAL_STATUS_SUCCESS != status) {
         WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                    "%s: failed to receive SMD_EVENT_REOPEN_READY",
                    __func__);
      }

      /* During the close sequence we deregistered from SMD.  As part
         of deregistration SMD will call back into our driver with an
         event to let us know the channel is closed.  We need to
         insert a brief delay to allow that thread of execution to
         exit our module.  Otherwise our module may be unloaded while
         there is still code running within the address space, and
         that code will crash when the memory is unmapped  */
      msleep(50);
   }

   /* channel has (hopefully) been closed */
   pWCTSCb->wctsNotifyCB((WCTS_HandleType)pWCTSCb,
                         WCTS_EVENT_CLOSE,
                         pWCTSCb->wctsNotifyCBData);

   /* release the resource */
   pWCTSCb->wctsMagic = 0;
   wpalMemoryFree(pWCTSCb);
   gwctsHandle = NULL;

   return eWLAN_PAL_STATUS_SUCCESS;

}/*WCTS_CloseTransport*/
Ejemplo n.º 4
0
/**
 @brief    Callback function for serializing WCTS Write
           processing in the control context

 @param    pWCTSCb  WCTS Control Block

 @see
 @return void
*/
static void
WCTS_PALWriteCallback
(
   WCTS_ControlBlockType*  pWCTSCb
)
{
   wpt_list_node*      pNode;
   WCTS_BufferType*    pBufferQueue;
   void*               pBuffer;
   int                 len;
   int                 available;
   int                 written;

   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*--------------------------------------------------------------------
     Sanity check
     --------------------------------------------------------------------*/
   if ((NULL == pWCTSCb) || (WCTS_CB_MAGIC != pWCTSCb->wctsMagic)) {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "WCTS_PALWriteCallback: Invalid parameter received.");
      return;
   }

   /* if we are not deferred, then there are no pending packets */
   if (WCTS_STATE_DEFERRED != pWCTSCb->wctsState) {
      return;
   }

   /* Keep sending deferred messages as long as there is room in
      the channel.  Note that we initially peek at the head of the
      list to access the parameters for the next message; we don't
      actually remove the next message from the deferred list until
      we know the channel can handle it */
   while (eWLAN_PAL_STATUS_SUCCESS ==
          wpal_list_peek_front(&pWCTSCb->wctsPendingQueue, &pNode)) {
      pBufferQueue = container_of(pNode, WCTS_BufferType, node);
      pBuffer = pBufferQueue->pBuffer;
      len = pBufferQueue->bufferSize;

      available = smd_write_avail(pWCTSCb->wctsChannel);
      if (available < len) {
         /* channel has no room for the next packet so we are done */
         return;
      }

      /* there is room for the next message, so we can now remove
         it from the deferred message queue and send it */
      wpal_list_remove_front(&pWCTSCb->wctsPendingQueue, &pNode);

      /* note that pNode will be the same as when we peeked, so
         there is no need to update pBuffer or len */

      written = smd_write(pWCTSCb->wctsChannel, pBuffer, len);
      if (written != len) {
         /* Something went wrong */
         WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                    "WCTS_PALWriteCallback: channel write failure");

         /* we were unable to send the message that was at the head
            of the deferred list.  there is nothing else we can do
            other than drop it, so we will just fall through to the
            "success" processing.
            hopefully the client can recover from this since there is
            nothing else we can do here */
      }

      /* whether we had success or failure, reclaim all memory */
      wpalMemoryFree(pBuffer);
      wpalMemoryFree(pBufferQueue);

      /* we'll continue to iterate until the channel is full or all
         of the deferred messages have been sent */
   }

   /* if we've exited the loop, then we have drained the deferred queue.
      set the state to indicate we are no longer deferred, and turn off
      the remote read interrupt */
   pWCTSCb->wctsState = WCTS_STATE_OPEN;
   smd_disable_read_intr(pWCTSCb->wctsChannel);

} /*WCTS_PALWriteCallback*/
Ejemplo n.º 5
0
wpt_uint32
WCTS_CloseTransport
(
   WCTS_HandleType      wctsHandle
)
{
   WCTS_ControlBlockType* pWCTSCb = (WCTS_ControlBlockType*) wctsHandle;
   wpt_list_node*      pNode = NULL;
   WCTS_BufferType*    pBufferQueue = NULL;
   void*               pBuffer = NULL;
   wpt_status          status;
   int                 smdstatus;

   

   if ((NULL == pWCTSCb) || (WCTS_CB_MAGIC != pWCTSCb->wctsMagic)) {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "WCTS_CloseTransport: Invalid parameters received.");
      return eWLAN_PAL_STATUS_E_INVAL;
   }

#ifdef FEATURE_R33D
   
   
   pWCTSCb->wctsState = WCTS_STATE_CLOSED;
   pWCTSCb->wctsNotifyCB((WCTS_HandleType)pWCTSCb,
                         WCTS_EVENT_CLOSE,
                         pWCTSCb->wctsNotifyCBData);

   printk(KERN_ERR "R33D Not need to close");
   return eWLAN_PAL_STATUS_SUCCESS;
#endif 

   
   while (eWLAN_PAL_STATUS_SUCCESS ==
          wpal_list_remove_front(&pWCTSCb->wctsPendingQueue, &pNode)) {
      pBufferQueue = container_of(pNode, WCTS_BufferType, node);
      pBuffer = pBufferQueue->pBuffer;
      wpalMemoryFree(pBuffer);
      wpalMemoryFree(pBufferQueue);
   }

   
   pWCTSCb->wctsState = WCTS_STATE_CLOSED;

   wpalEventReset(&pWCTSCb->wctsEvent);
   smdstatus = smd_close(pWCTSCb->wctsChannel);
   if (0 != smdstatus) {
      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                 "%s: smd_close failed with status %d",
                 __func__, smdstatus);

   } else {
      
      status = wpalEventWait(&pWCTSCb->wctsEvent, WCTS_SMD_CLOSE_TIMEOUT);
      if (eWLAN_PAL_STATUS_SUCCESS != status) {
         WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
                    "%s: failed to receive SMD_EVENT_REOPEN_READY",
                    __func__);
      }

      msleep(50);
   }

   
   pWCTSCb->wctsNotifyCB((WCTS_HandleType)pWCTSCb,
                         WCTS_EVENT_CLOSE,
                         pWCTSCb->wctsNotifyCBData);

   
   pWCTSCb->wctsMagic = 0;
   wpalMemoryFree(pWCTSCb);
   gwctsHandle = NULL;

   return eWLAN_PAL_STATUS_SUCCESS;

}