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

📄 pcnet.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 3 页
字号:

  /* initialize tx descriptors */
  TransmitDescriptor = Adapter->TransmitDescriptorRingVirt;
  for(i = 0; i < NUMBER_OF_BUFFERS; i++)
    {
      (TransmitDescriptor+i)->TBADR = (ULONG)Adapter->TransmitBufferPtrPhys + i * BUFFER_SIZE;
      (TransmitDescriptor+i)->BCNT = 0xf000 | -BUFFER_SIZE; /* 2's compliment  + set top 4 bits */
      (TransmitDescriptor+i)->FLAGS = TD1_STP | TD1_ENP;
    }

  DPRINT("transmit ring initialized\n");

  /* initialize rx */
  ReceiveDescriptor = Adapter->ReceiveDescriptorRingVirt;
  for(i = 0; i < NUMBER_OF_BUFFERS; i++)
    {
      (ReceiveDescriptor+i)->RBADR = (ULONG)Adapter->ReceiveBufferPtrPhys + i * BUFFER_SIZE;
      (ReceiveDescriptor+i)->BCNT = 0xf000 | -BUFFER_SIZE; /* 2's compliment  + set top 4 bits */
      (ReceiveDescriptor+i)->FLAGS = RD_OWN;
    }

  DPRINT("receive ring initialized\n");

  return NDIS_STATUS_SUCCESS;
}

static VOID
MiPrepareInitializationBlock(
    PADAPTER Adapter)
/*
 * FUNCTION: Initialize the initialization block
 * ARGUMENTS:
 *     Adapter: pointer to the miniport's adapter object
 */
{
  ULONG i = 0;

  RtlZeroMemory(Adapter->InitializationBlockVirt, sizeof(INITIALIZATION_BLOCK));

  /* read burned-in address from card */
  for(i = 0; i < 6; i++)
    NdisRawReadPortUchar(Adapter->PortOffset + i, Adapter->InitializationBlockVirt->PADR + i);
  DPRINT("MAC address: %02x-%02x-%02x-%02x-%02x-%02x\n",
         Adapter->InitializationBlockVirt->PADR[0],
         Adapter->InitializationBlockVirt->PADR[1],
         Adapter->InitializationBlockVirt->PADR[2],
         Adapter->InitializationBlockVirt->PADR[3],
         Adapter->InitializationBlockVirt->PADR[4],
         Adapter->InitializationBlockVirt->PADR[5]);

  /* set up receive ring */
  DPRINT("Receive ring physical address: 0x%x\n", Adapter->ReceiveDescriptorRingPhys);
  Adapter->InitializationBlockVirt->RDRA = (ULONG)Adapter->ReceiveDescriptorRingPhys;
  Adapter->InitializationBlockVirt->RLEN = (LOG_NUMBER_OF_BUFFERS << 4) & 0xf0;

  /* set up transmit ring */
  DPRINT("Transmit ring physical address: 0x%x\n", Adapter->TransmitDescriptorRingPhys);
  Adapter->InitializationBlockVirt->TDRA = (ULONG)Adapter->TransmitDescriptorRingPhys;
  Adapter->InitializationBlockVirt->TLEN = (LOG_NUMBER_OF_BUFFERS << 4) & 0xf0;
}

static VOID
MiFreeSharedMemory(
    PADAPTER Adapter)
/*
 * FUNCTION: Free all allocated shared memory
 * ARGUMENTS:
 *     Adapter: pointer to the miniport's adapter struct
 */
{
  NDIS_PHYSICAL_ADDRESS PhysicalAddress;

  PhysicalAddress.u.HighPart = 0;

  if(Adapter->InitializationBlockVirt)
    {
      PhysicalAddress.u.LowPart = (ULONG)Adapter->InitializationBlockPhys;
      NdisMFreeSharedMemory(Adapter->MiniportAdapterHandle, Adapter->InitializationBlockLength,
          FALSE, Adapter->InitializationBlockVirt, PhysicalAddress);
    }

  if(Adapter->TransmitDescriptorRingVirt)
    {
      PhysicalAddress.u.LowPart = (ULONG)Adapter->TransmitDescriptorRingPhys;
      NdisMFreeSharedMemory(Adapter->MiniportAdapterHandle, Adapter->TransmitDescriptorRingLength,
        FALSE, Adapter->TransmitDescriptorRingVirt, PhysicalAddress);
    }

  if(Adapter->ReceiveDescriptorRingVirt)
    {
      PhysicalAddress.u.LowPart = (ULONG)Adapter->ReceiveDescriptorRingPhys;
      NdisMFreeSharedMemory(Adapter->MiniportAdapterHandle, Adapter->ReceiveDescriptorRingLength,
          FALSE, Adapter->ReceiveDescriptorRingVirt, PhysicalAddress);
    }

  if(Adapter->TransmitBufferPtrVirt)
    {
      PhysicalAddress.u.LowPart = (ULONG)Adapter->TransmitBufferPtrPhys;
      NdisMFreeSharedMemory(Adapter->MiniportAdapterHandle, Adapter->TransmitBufferLength,
          FALSE, Adapter->TransmitBufferPtrVirt, PhysicalAddress);
    }

  if(Adapter->ReceiveBufferPtrVirt)
    {
      PhysicalAddress.u.LowPart = (ULONG)Adapter->ReceiveBufferPtrPhys;
      NdisMFreeSharedMemory(Adapter->MiniportAdapterHandle, Adapter->ReceiveBufferLength,
          FALSE, Adapter->ReceiveBufferPtrVirt, PhysicalAddress);
    }
}

static BOOLEAN
STDCALL
MiSyncStop(
    IN PVOID SynchronizeContext)
/*
 * FUNCTION: Stop the adapter
 * ARGUMENTS:
 *     SynchronizeContext: Adapter context
 */
{
  PADAPTER Adapter = (PADAPTER)SynchronizeContext;
  NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR0);
  NdisRawWritePortUshort(Adapter->PortOffset + RDP, CSR0_STOP);
  return TRUE;
}

static VOID
STDCALL
MiniportHalt(
    IN NDIS_HANDLE MiniportAdapterContext)
/*
 * FUNCTION: Stop the adapter and release any per-adapter resources
 * ARGUMENTS:
 *     MiniportAdapterContext: context specified to NdisMSetAttributes
 * NOTES:
 *     - Called by NDIS at PASSIVE_LEVEL
 */
{
  PADAPTER Adapter = (PADAPTER)MiniportAdapterContext;
  BOOLEAN TimerCancelled;

  DPRINT("Called\n");
  ASSERT(Adapter);

  /* stop the media detection timer */
  NdisMCancelTimer(&Adapter->MediaDetectionTimer, &TimerCancelled);

  /* stop the chip */
  NdisMSynchronizeWithInterrupt(&Adapter->InterruptObject, MiSyncStop, Adapter);

  /* deregister the interrupt */
  NdisMDeregisterInterrupt(&Adapter->InterruptObject);

  /* deregister i/o port range */
  NdisMDeregisterIoPortRange(Adapter->MiniportAdapterHandle, Adapter->IoBaseAddress, NUMBER_OF_PORTS, (PVOID)Adapter->PortOffset);

  /* free shared memory */
  MiFreeSharedMemory(Adapter);

  /* free map registers */
  NdisMFreeMapRegisters(Adapter->MiniportAdapterHandle);

  /* free the lock */
  NdisFreeSpinLock(&Adapter->Lock);

  /* free the adapter */
  NdisFreeMemory(Adapter, 0, 0);
}

static BOOLEAN
STDCALL
MiSyncMediaDetection(
    IN PVOID SynchronizeContext)
/*
 * FUNCTION: Stop the adapter
 * ARGUMENTS:
 *     SynchronizeContext: Adapter context
 */
{
  PADAPTER Adapter = (PADAPTER)SynchronizeContext;
  NDIS_MEDIA_STATE MediaState = MiGetMediaState(Adapter);

  DPRINT("Called\n");
  DPRINT("MediaState: %d\n", MediaState);
  if (MediaState != Adapter->MediaState)
    {
      Adapter->MediaState = MediaState;
      return TRUE;
    }
  return FALSE;
}

static VOID
STDCALL
MiniportMediaDetectionTimer(
    IN PVOID SystemSpecific1,
    IN PVOID FunctionContext,
    IN PVOID SystemSpecific2,
    IN PVOID SystemSpecific3)
/*
 * FUNCTION: Periodially query media state
 * ARGUMENTS:
 *     FunctionContext: Adapter context
 * NOTES:
 *     - Called by NDIS at DISPATCH_LEVEL
 */
{
  PADAPTER Adapter = (PADAPTER)FunctionContext;

  if (NdisMSynchronizeWithInterrupt(&Adapter->InterruptObject,
                                    MiSyncMediaDetection,
                                    FunctionContext))
    {
      NdisMIndicateStatus(Adapter->MiniportAdapterHandle,
        Adapter->MediaState == NdisMediaStateConnected ?
        NDIS_STATUS_MEDIA_CONNECT : NDIS_STATUS_MEDIA_DISCONNECT,
        (PVOID)0, 0);
      NdisMIndicateStatusComplete(Adapter->MiniportAdapterHandle);
    }
}

static VOID
MiInitChip(
    PADAPTER Adapter)
/*
 * FUNCTION: Initialize and start the PCNET chip
 * ARGUMENTS:
 *     Adapter: pointer to the miniport's adapter struct
 * NOTES:
 *     - should be coded to detect failure and return an error
 *     - the vmware virtual lance chip doesn't support 32-bit i/o so don't do that.
 */
{
  USHORT Data = 0;

  DPRINT("Called\n");

  /*
   * first reset the chip - 32-bit reset followed by 16-bit reset.  if it's in 32-bit mode, it'll reset
   * twice.  if it's in 16-bit mode, the first read will be nonsense and the second will be a reset.  the
   * card is reset by reading from the reset register.  on reset it's in 16-bit i/o mode.
   */
  NdisRawReadPortUshort(Adapter->PortOffset + RESET32, &Data);
  NdisRawReadPortUshort(Adapter->PortOffset + RESET16, &Data);

  /* stop the chip */
  NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR0);
  NdisRawWritePortUshort(Adapter->PortOffset + RDP, CSR0_STOP);

  /* pause for 1ms so the chip will have time to reset */
  NdisStallExecution(1);

  DPRINT("chip stopped\n");

  /* set the software style to 2 (32 bits) */
  NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR58);
  NdisRawReadPortUshort(Adapter->PortOffset + RDP, &Data);

  Data |= SW_STYLE_2;

  NdisRawWritePortUshort(Adapter->PortOffset + RDP, Data);

  /* set up csr4: auto transmit pad, disable polling, disable transmit interrupt, dmaplus */
  NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR4);
  NdisRawReadPortUshort(Adapter->PortOffset + RDP, &Data);

  Data |= CSR4_APAD_XMT | /* CSR4_DPOLL |*/ CSR4_TXSTRTM | CSR4_DMAPLUS;
  NdisRawWritePortUshort(Adapter->PortOffset + RDP, Data);

  /* set up bcr18: burst read/write enable */
  NdisRawWritePortUshort(Adapter->PortOffset + RAP, BCR18);
  NdisRawReadPortUshort(Adapter->PortOffset + BDP, &Data);

  Data |= BCR18_BREADE | BCR18_BWRITE ;
  NdisRawWritePortUshort(Adapter->PortOffset + BDP, Data);

  /* set up csr1 and csr2 with init block */
  NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR1);
  NdisRawWritePortUshort(Adapter->PortOffset + RDP, (USHORT)((ULONG)Adapter->InitializationBlockPhys & 0xffff));
  NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR2);
  NdisRawWritePortUshort(Adapter->PortOffset + RDP, (USHORT)((ULONG)Adapter->InitializationBlockPhys >> 16) & 0xffff);

  DPRINT("programmed with init block\n");

  /* Set mode to 0 */
  Data = 0;
  NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR15);
  NdisRawWritePortUshort(Adapter->PortOffset + RDP, Data);

  /* load init block and start the card */
  NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR0);
  NdisRawWritePortUshort(Adapter->PortOffset + RDP, CSR0_STRT|CSR0_INIT|CSR0_IENA);

  /* detect the media state */
  NdisRawWritePortUshort(Adapter->PortOffset + RAP, BCR4);
  NdisRawWritePortUshort(Adapter->PortOffset + BDP, BCR4_LNKSTE|BCR4_FDLSE);
  Adapter->MediaState = MiGetMediaState(Adapter);

  DPRINT("card started\n");

  Adapter->Flags &= ~RESET_IN_PROGRESS;
}

#if DBG
static BOOLEAN
MiTestCard(
    PADAPTER Adapter)
/*
 * FUNCTION: Test the NIC
 * ARGUMENTS:
 *     Adapter: pointer to the miniport's adapter struct
 * RETURNS:
 *     TRUE if the test succeeds
 *     FALSE otherwise
 * NOTES:
 *     - this is where to add diagnostics.  This is called
 *       at the very end of initialization.
 */
{
  int i = 0;
  UCHAR address[6];
  USHORT Data = 0;

  /* see if we can read/write now */
  NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR0);
  NdisRawReadPortUshort(Adapter->PortOffset + RDP, &Data);
  DPRINT("Port 0x%x RAP 0x%x CSR0 0x%x RDP 0x%x, Interupt status register is 0x%x\n", Adapter->PortOffset, RAP, CSR0, RDP, Data);

  /* read the BIA */
  for(i = 0; i < 6; i++)
      NdisRawReadPortUchar(Adapter->PortOffset + i, &address[i]);

  DPRINT("burned-in address: %x:%x:%x:%x:%x:%x\n", address[0], address[1], address[2], address[3], address[4], address[5]);
  /* Read status flags from CSR0 */
  NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR0);
  NdisRawReadPortUshort(Adapter->PortOffset + RDP, &Data);
  DPRINT("CSR0: 0x%x\n", Data);

  /* Read status flags from CSR3 */
  NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR3);
  NdisRawReadPortUshort(Adapter->PortOffset + RDP, &Data);

  DPRINT("CSR3: 0x%x\n", Data);
  /* Read status flags from CSR4 */
  NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR4);
  NdisRawReadPortUshort(Adapter->PortOffset + RDP, &Data);
  DPRINT("CSR4: 0x%x\n", Data);

  /* Read status flags from CSR5 */
  NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR5);
  NdisRawReadPortUshort(Adapter->PortOffset + RDP, &Data);
  DPRINT("CSR5: 0x%x\n", Data);

  /* Read status flags from CSR6 */
  NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR6);
  NdisRawReadPortUshort(Adapter->PortOffset + RDP, &Data);
  DPRINT("CSR6: 0x%x\n", Data);

  return TRUE;
}
#endif

static NDIS_STATUS
STDCALL
MiniportInitialize(
    OUT PNDIS_STATUS OpenErrorStatus,
    OUT PUINT SelectedMediumIndex,
    IN PNDIS_MEDIUM MediumArray,
    IN UINT MediumArraySize,
    IN NDIS_HANDLE MiniportAdapterHandle,
    IN NDIS_HANDLE WrapperConfigurationContext)
/*
 * FUNCTION:  Initialize a new miniport
 * ARGUMENTS:
 *     OpenErrorStatus:  pointer to a var to return status info in
 *     SelectedMediumIndex: index of the selected medium (will be NdisMedium802_3)
 *     MediumArray: array of media that we can pick from
 *     MediumArraySize: size of MediumArray
 *     MiniportAdapterHandle: NDIS-assigned handle for this miniport instance
 *     WrapperConfigurationContext: temporary NDIS-assigned handle for passing
 *                                  to configuration APIs
 * RETURNS:
 *     NDIS_STATUS_SUCCESS on success
 *     NDIS_STATUS_FAILURE on general failure
 *     NDIS_STATUS_UNSUPPORTED_MEDIA on not finding 802_3 in the MediaArray
 *     NDIS_STATUS_RESOURCES on insufficient system resources
 *     NDIS_STATUS_ADAPTER_NOT_FOUND on not finding the adapter
 * NOTES:
 *     - Called by NDIS at PASSIVE_LEVEL, once per detected card
 *     - Will int 3 on failure of MiTestCard if DBG=1
 */
{
  UINT i = 0;
  PADAPTER Adapter = 0;
  NDIS_STATUS Status = NDIS_STATUS_FAILURE;
  BOOLEAN InterruptRegistered = FALSE;

  /* Pick a medium */
  for(i = 0; i < MediumArraySize; i++)
    if(MediumArray[i] == NdisMedium802_3)
      break;

  if(i == MediumArraySize)
    {
      Status = NDIS_STATUS_UNSUPPORTED_MEDIA;
      DPRINT1("unsupported media\n");
      BREAKPOINT;
      *OpenErrorStatus = Status;
      return Status;
    }

  *SelectedMediumIndex = i;

  /* allocate our adapter struct */
  Status = NdisAllocateMemoryWithTag((PVOID *)&Adapter, sizeof(ADAPTER), PCNET_TAG);
  if(Status != NDIS_STATUS_SUCCESS)
    {

⌨️ 快捷键说明

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