Exemple #1
0
/*-------------------------------------------------------------------------
  ssh_driver_set_information()

  Request changes in the state of virtual NIC. All but OID_PNP_SET_POWER,
  OID_PNP_ENABLE_WAKE_UP and OID_TCP_TASK_OFFLOAD change requests are 
  passed down to the underlaying NIC.

  
  Arguments:
  miniport_context - virtual NIC object
  oid - change request operation identifier
  info - data for change operation
  info_len - data buffer length
  bytes_read - how many bytes has been read from info buffer
  bytes_needed - how many bytes is needed to complete the set operation
                 successfully

  Returns:
  NDIS_STATUS_SUCCESS - query completed successfully,
  NDIS_STATUS_PENDING - change request completion pending,
  NDIS_STATUS_RESOURCES - resource allocation for change request failed
  
  Notes:                                                         
  
  Default IRQL: DISPATCH_LEVEL
  -------------------------------------------------------------------------*/
static NDIS_STATUS
ssh_driver_set_information(NDIS_HANDLE miniport_context,
                           NDIS_OID oid,
                           PVOID info,
                           ULONG info_len,
                           PULONG bytes_read,
                           PULONG bytes_needed)
{
  SshNdisIMAdapter adapter = (SshNdisIMAdapter)miniport_context;
  struct _SET_INFORMATION *set;
  SshRequest request;
  NDIS_STATUS status;
  PVOID info_buf = info;

  SSH_ASSERT(SSH_GET_IRQL() <= SSH_DISPATCH_LEVEL);
  SSH_ASSERT(adapter != NULL);

  if (info)
    SSH_DEBUG_HEXDUMP(SSH_D_MIDSTART,
                      ("Adapter %@ MiniportSetInformation: oid=%@, data:",
                       ssh_adapter_id_st_render, adapter, 
                       ssh_ndis_oid_render, &oid),
                      info, info_len);
  else
    SSH_DEBUG(SSH_D_MIDSTART,
              ("Adapter %@ MiniportSetInformation: oid=%@",
               ssh_adapter_id_st_render, adapter, 
               ssh_ndis_oid_render, &oid));

  /* OID_PNP_SET_POWER must be handled by us (not forwarded to underlyng
     miniport driver). */
  if (oid == OID_PNP_SET_POWER)
    {
      status = ssh_adapter_handle_set_power(adapter, info, info_len,
                                            bytes_read, bytes_needed);
      goto end;
    }

#ifdef _WIN32_WCE
  *bytes_read = 0;
  *bytes_needed = 0;
#else
  if (MmIsAddressValid(bytes_read))
    *bytes_read = 0;
  if (MmIsAddressValid(bytes_needed))
    *bytes_needed = 0;
  
  /* Check if the address for operation is within user space */ 
  if (info_len > 0 && info <= MM_HIGHEST_USER_ADDRESS)
    {
      /* Map user space address to system address */
      PMDL mdl = IoAllocateMdl(info, info_len, FALSE, FALSE, NULL);
      if (!mdl)
        {
          info_buf = NULL;
        }
      else
        {
          info_buf = MmGetSystemAddressForMdlSafe(mdl, LowPagePriority);
          IoFreeMdl(mdl);
        }
    }

  /* Check if address is valid */
  if (info_len > 0 && !MmIsAddressValid(info_buf))
    {
      status = NDIS_STATUS_NOT_ACCEPTED;
      goto end;
    }
#endif /* _WIN32_WCE */
  
  /* Allocate memory for the request */
  request = NdisAllocateFromNPagedLookasideList(&adapter->request_list);
  if (request == NULL)
    {
      status = NDIS_STATUS_RESOURCES;
      goto end;
    }

  /* Fill the data for our request */
  request->orig_request.RequestType = NdisRequestSetInformation;
  request->bytes_read_written = bytes_read;
  request->bytes_needed = bytes_needed;
  request->request_done_cb = ssh_adapter_set_request_done;
  request->asynch_completion = TRUE;
  request->queued = FALSE;

  set = &(request->orig_request.DATA.SET_INFORMATION);
  set->Oid = oid;
  set->InformationBuffer = info_buf;
  set->InformationBufferLength = info_len;
  set->BytesRead = 0;
  set->BytesNeeded = 0;

  status = ssh_adapter_handle_set_request(adapter, &request->orig_request);

 end:
  SSH_DEBUG(SSH_D_MIDOK,
            ("Adapter %@ MiniportSetInformation: status=%@", 
             ssh_adapter_id_st_render, adapter, 
             ssh_ndis_status_render, &status));

  return (status);
}
Exemple #2
0
NDIS_STATUS
BasePortTranslateTxNBLsToTxPackets(
    __in  PMP_PORT                Port,
    __in  PNET_BUFFER_LIST        NetBufferLists,
    __out PMP_TX_MSDU  *          PacketList
    )
{
    PMP_TX_MSDU                 outputPacketList = NULL;
    PMP_TX_MSDU                 currentPacket, prevPacket = NULL;
    PMP_TX_MPDU                 currentFragment;
    USHORT                      fragmentIndex = 0;
    PNET_BUFFER_LIST            currentNetBufferList = NetBufferLists, nextNetBufferList;
    PNET_BUFFER                 currentNetBuffer;
    NDIS_STATUS                 ndisStatus = NDIS_STATUS_SUCCESS;
    PDOT11_EXTSTA_SEND_CONTEXT  osSendContext, mySendContext;  // This is same for ExtAP & ExtSTA

    *PacketList = NULL;

    // Convert each NBL and NB to our structure    
    while (currentNetBufferList != NULL)
    {
        nextNetBufferList = NET_BUFFER_LIST_NEXT_NBL(currentNetBufferList);

        // First the MP_TX_MSDU  
        currentPacket = NdisAllocateFromNPagedLookasideList(&(Port->TxPacketLookaside));
        if (currentPacket == NULL)
        {
            MpTrace(COMP_SEND, DBG_SERIOUS, ("Failed to allocate MP_TX_MSDU   for NET_BUFFER_LIST\n"));        
            ndisStatus = NDIS_STATUS_RESOURCES;
            break;
        }
        NdisZeroMemory(currentPacket, sizeof(MP_TX_MSDU  ));
        
        // Populate the TX_PACKET
        MP_TX_MSDU_WRAPPED_NBL(currentPacket) = currentNetBufferList;
        // Save the TX_MSDU in the NET_BUFFER_LIST for debugging purpose
        MP_NBL_WRAPPED_TX_MSDU(currentNetBufferList) = currentPacket;

        osSendContext = MP_GET_SEND_CONTEXT(currentNetBufferList);
        mySendContext = MP_TX_MSDU_SEND_CONTEXT(currentPacket);
        NdisMoveMemory(mySendContext, osSendContext, sizeof(DOT11_EXTSTA_SEND_CONTEXT));
        
        if (outputPacketList == NULL)
        {
            outputPacketList = currentPacket;
        }
        else
        {
            MP_TX_MSDU_NEXT_MSDU(prevPacket) = currentPacket;
        }
        // The Next NBL's PACKET would be added after the current NBL's PACKET
        prevPacket = currentPacket;

        // Now we go through the NBs in this NB
        fragmentIndex = 0;
        for (currentNetBuffer = NET_BUFFER_LIST_FIRST_NB(currentNetBufferList);
             currentNetBuffer != NULL;
             currentNetBuffer = NET_BUFFER_NEXT_NB(currentNetBuffer))
        {
            currentFragment = NdisAllocateFromNPagedLookasideList(&(Port->TxFragmentLookaside));
            if (currentFragment == NULL)
            {
                MpTrace(COMP_SEND, DBG_SERIOUS, ("Failed to allocate MP_TX_MPDU     for NET_BUFFER\n"));        
                ndisStatus = NDIS_STATUS_RESOURCES;
                break;
            }
            NdisZeroMemory(currentFragment, sizeof(MP_TX_MPDU    ));

            // Populate the TX_FRAGMENT
            MP_TX_MPDU_WRAPPED_NB(currentFragment) = currentNetBuffer;
            MP_TX_MPDU_MSDU(currentFragment) = currentPacket;

            // Add it to the fragment list of the packet
            MP_TX_MSDU_MPDU_AT(currentPacket, fragmentIndex) = currentFragment;
            fragmentIndex++;
        }
        MP_TX_MSDU_MPDU_COUNT(currentPacket) = fragmentIndex;        
        
        if (ndisStatus != NDIS_STATUS_SUCCESS)
        {
            break;
        }
        
        currentNetBufferList = nextNetBufferList;
    }


    if (ndisStatus != NDIS_STATUS_SUCCESS)
    {
        if (outputPacketList != NULL)
        {
            BasePortFreeTranslatedTxPackets(Port, outputPacketList);
            outputPacketList = NULL;
        }
    }

    *PacketList = outputPacketList;

    return ndisStatus;
}