Пример #1
0
/**
 * @brief mystrcpy
 *
 * Easy to use wrapper for strcpy to make it safe against buffer
 * overflows and to report any truncations.
 */
void mystrcpy(char *dst, size_t dstSize, const char *src)
{
	size_t  srcLen;

	if (dst == NULL)
	{
		ErrPrint("mystrcpy null dst\n");
		return;
	}

	if (dstSize < 1)
	{
		ErrPrint("mystrcpy invalid dst size\n");
		return;
	}

	dst[ 0 ] = 0;

	if (src == NULL)
	{
		ErrPrint("mystrcpy null src\n");
		return;
	}

	srcLen = strlen(src);

	if (srcLen >= dstSize)
	{
		ErrPrint("mystrcpy buffer overflow on '%s'\n", src);
		srcLen = dstSize - 1;
	}

	memcpy(dst, src, srcLen);
	dst[ srcLen ] = 0;
}
Пример #2
0
/*
 * Configures link settings.
 * Assumes the hardware has previously been reset and the
 * transmitter and receiver are not enabled.
 */
SInt32 AtherosL1Ethernet::atSetupLink()
{
    SInt32 ret_val;

    /*
     * Options:
     *  PHY will advertise value(s) parsed from
     *  autoneg_advertised and fc
     *  no matter what autoneg is , We will not wait link result.
     */
    at_hw *hw = &adapter_.hw;
    
    ret_val = at_phy_setup_autoneg_adv(hw);
    if (ret_val) 
    {
        ErrPrint("setting up autonegotiation\n");
        return ret_val;
    }
    /* SW.Reset , En-Auto-Neg if needed */
    ret_val = at_phy_commit(hw);
    if (ret_val) 
    {
        ErrPrint("resetting the phy\n");
        return ret_val;
    }
    //hw->phy_configured = true;
    return ret_val;
}
Пример #3
0
int sortText(Text_t *text, int key, int *StringCount, size_t Textlen)
{
	assert(text);
	if (!text) Nerror = MEMERR;
	ErrPrint(Nerror);
	if (key == 1)
	{
		int jump = *StringCount;
		bool swapped = true;
		while (jump > 1 || swapped)
		{
			if (jump > 1)
				jump /= 1.24733;
			swapped = false;
			for (int i = 0; i + jump < *StringCount; ++i)
			{
				assert(&text[i] && &text[i + jump]);
				if (!(&text[i]) && !(&text[i + jump])) Nerror = STRERR;
				if (mlStrcmp((&text[i + jump])->StringPos, (&text[i])->StringPos) == -1)
				{
					if (!(&text[i]) && !(&text[i + jump])) Nerror = STRERR;
					assert(&text[i] && &text[i + jump]);
					swapPtr(&text[i], &text[i + jump]);
					swapped = true;
				}
				ErrPrint(Nerror);
			}
		}
	}
	else if (key == 2)
	{
		int jump = *StringCount;
		bool swapped = true;
		while (jump > 1 || swapped)
		{
			if (jump > 1)
				jump /= 1.24733;
			swapped = false;
			for (int i = 0; i + jump < *StringCount; ++i)
			{
				if (!(&text[i]) && !(&text[i + jump])) Nerror = STRERR;
				if (mlStrcmpEnd(text[i + jump], text[i]) == -1)
				{
					assert(&text[i] && &text[i + jump]);
					if (!(&text[i]) && !(&text[i + jump])) Nerror = STRERR;
					swapPtr(&text[i], &text[i + jump]);
					swapped = true;
				}
				ErrPrint(Nerror);
			}
		}
	}
	findEnd(text, StringCount, Textlen, key);
	return 1;
}
Пример #4
0
/**
 * @brief mystrcat
 *
 * Easy to use wrapper for strcat to make it safe against buffer
 * overflows and to report any truncations.
 */
void mystrcat(char *dst, size_t dstSize, const char *src)
{
	size_t  dstLen;
	size_t  srcLen;
	size_t  maxLen;

	if (dst == NULL)
	{
		ErrPrint("mystrcat null dst\n");
		return;
	}

	if (dstSize < 1)
	{
		ErrPrint("mystrcat invalid dst size\n");
		return;
	}

	dstLen = strlen(dst);

	if (dstLen >= dstSize)
	{
		ErrPrint("mystrcat invalid dst len\n");
		return;
	}

	if (src == NULL)
	{
		ErrPrint("mystrcat null src\n");
		return;
	}

	srcLen = strlen(src);

	if (srcLen < 1)
	{
		/* empty string, do nothing */
		return;
	}

	maxLen = (dstSize - 1) - dstLen;

	if (srcLen > maxLen)
	{
		ErrPrint("mystrcat buffer overflow\n");
		srcLen = maxLen;
	}

	if (srcLen > 0)
	{
		memcpy(dst + dstLen, src, srcLen);
		dst[ dstLen + srcLen ] = 0;
	}
}
Пример #5
0
IOReturn AtherosL1Ethernet::getHardwareAddress(IOEthernetAddress *addr)
{
    DbgPrint("getHardwareAddress()\n");
    IOSleep(1000);

    if (is_valid_ether_addr(adapter_.hw.mac_addr))
    {
        memcpy(addr->bytes, adapter_.hw.mac_addr, NODE_ADDRESS_SIZE);
        return kIOReturnSuccess;
    }

    if (get_permanent_address(&adapter_.hw) == 0)
    {
        if (is_valid_ether_addr(adapter_.hw.perm_mac_addr))
        {
            memcpy(adapter_.hw.mac_addr, adapter_.hw.perm_mac_addr, NODE_ADDRESS_SIZE);
            memcpy(addr->bytes, adapter_.hw.mac_addr, NODE_ADDRESS_SIZE);
        }
        else
        {
            ErrPrint("Invalid mac address\n");
            return kIOReturnUnsupported;
        }
        return kIOReturnSuccess;
    }
    else
    {
        DbgPrint("Couldn't get device mac address\n");
        memcpy(adapter_.hw.mac_addr, addr->bytes, NODE_ADDRESS_SIZE);
        //return kIOReturnUnsupported;
        return kIOReturnSuccess;
    }
}
Пример #6
0
int mlStrcmpEnd(Text_t string1, Text_t string2)
{
	int i = 0;

	assert(string1.StringPos && string2.StringPos);
	if (!string1.StringPos || !string2.StringPos)
		Nerror = STRPOSERR;
	//perror("String is fault\n");

	i = 1;
	int j = 1;

	if (string2.StringPos[string2.lenghtString] >= 'A' && string2.StringPos[string2.lenghtString] <= 'Z' && string1.StringPos[string1.lenghtString] >= 'A' && string1.StringPos[string1.lenghtString] <= 'Z')
		return 0;
	else while (string1.lenghtString - i + 1 >= 0 && string2.lenghtString - j + 1 >= 0)
	{
		while (IsPunct(string1.StringPos, string1.lenghtString + 1 - i))
			i++;
		while (IsPunct(string2.StringPos, string2.lenghtString + 1 - j))
			j++;
		if (!IsPunct(string1.StringPos, string1.lenghtString + 1 - i) && !IsPunct(string2.StringPos, string2.lenghtString + 1 - j))
		{
			if (string1.StringPos[string1.lenghtString + 1 - i] == string2.StringPos[string2.lenghtString + 1 - j])
			{
				i++;
				j++;
			}
			return string1.StringPos[string1.lenghtString + 1 - i] > string2.StringPos[string2.lenghtString + 1 - j] ? 1 : string1.StringPos[string1.lenghtString + 1 - i] < string2.StringPos[string2.lenghtString + 1 - j] ? -1 : 0;
		}
	}
	ErrPrint(Nerror);
	return 0;
}
Пример #7
0
int mlStrcmp(char* string1, char* string2)
{
	int i = 0, j = 0;

	if (string1 || string2)
		Nerror = STRERR;
	assert(string1 && string2);
	if (!string1 || !string2) perror("String is fault\n");

	while (string1[i] != '\r' && string2[j] != '\r')
	{
		while (IsPunct(string1, i))
			i++;
		while (IsPunct(string2, j))
			j++;
		if (!IsPunct(string1, i) && !IsPunct(string2, j))
		{
			assert(string1[i] && string2[j]);
			if (string1[i] || string2[j])
				Nerror = STRPOSERR;
			if (!string1[i] || !string2[j]) perror("Symbol is fault\n");
			if (string1[i] == string2[j])
			{
				i++;
				j++;
			}
			else return (string1[i] > string2[j]) ? 1 : (string1[i] < string2[j]) ? -1 : 0;
		}
	}
	ErrPrint(Nerror);
	return 0;
}
Пример #8
0
int IsPunct(char* string, int numb)
{
	assert(string[numb]);
	if (string[numb])
		Nerror = STRPOSERR;
	return (unsigned int)string[numb] > 0 && (unsigned int)string[numb] < 48 || (unsigned int)string[numb] > 57 && (unsigned int)string[numb] < 64 ||
		(unsigned int)string[numb] == '«' || (unsigned int)string[numb] == '»' || (unsigned int)string[numb] == '—' ? 1 : 0;
	ErrPrint(Nerror);
}
Пример #9
0
/**
 * @brief mysprintf
 *
 * Easy to use wrapper for sprintf to make it safe against buffer
 * overflows and to report any truncations.
 */
void mysprintf(char *dst, size_t dstSize, const char *fmt, ...)
{
	va_list         args;
	int             n;

	if (dst == NULL)
	{
		ErrPrint("mysprintf null dst\n");
		return;
	}

	if (dstSize < 1)
	{
		ErrPrint("mysprintf invalid dst size\n");
		return;
	}

	dst[ 0 ] = 0;

	if (fmt == NULL)
	{
		ErrPrint("mysprintf null fmt\n");
		return;
	}

	va_start(args, fmt);

	n = vsnprintf(dst, dstSize, fmt, args);

	if (n < 0)
	{
		ErrPrint("mysprintf error\n");
		dst[ 0 ] = 0;
	}
	else if (((size_t) n) >= dstSize)
	{
		ErrPrint("mysprintf buffer overflow\n");
		dst[ dstSize - 1 ] = 0;
	}

	va_end(args);
}
Пример #10
0
void swapPtr(Text_t *first, Text_t *second)
{
	assert(first && second);
	if (!first || !second)
		Nerror = PTRERR;
	//	perror("Pointers are damaged \n");
	Text_t tmp = *first;
	*first = *second;
	*second = tmp;
	ErrPrint(Nerror);
}
Пример #11
0
IOReturn AttansicL2Ethernet::enable(IONetworkInterface *netif)
{
	DbgPrint("enable()\n");
	
	u32 val;
	at_adapter *adapter=&adapter_;
	
	if (!adapter->pdev || (!adapter->pdev->isOpen () && (adapter->pdev->open(this)) == 0)) {
	    DbgPrint( "failed to open PCI device.\n");
        return kIOReturnError;
    }
  
	// hardware init
	if (at_init_hw(&adapter->hw))
	{
		ErrPrint("Couldn't init hw\n");
		//stop(provider);
		return kIOReturnError;
	}
	// hardware has been reset, we need to reload some things 
	init_ring_ptrs(adapter);

	at_configure(adapter);
	

	//PHY medium selection
	const IONetworkMedium *medium = getSelectedMedium();
	if (!medium)
	{
		DbgPrint("Selected medium is NULL, forcing to autonegotiation\n");
		medium = mediumTable[MEDIUM_INDEX_AUTO];
	}
	else
	{
		DbgPrint("Selected medium index %d\n", medium->getIndex());
	}


	selectMedium(medium);

	transmitQueue_->setCapacity(kTransmitQueueCapacity);
	transmitQueue_->start();
	
	// Enable interrupts. 
    val = AT_READ_REG(&adapter->hw, REG_MASTER_CTRL);
    AT_WRITE_REG(&adapter->hw, REG_MASTER_CTRL, val|MASTER_CTRL_MANUAL_INT);

	at_irq_enable(adapter);

	return kIOReturnSuccess;
}
Пример #12
0
bool AtherosL1Ethernet::init(OSDictionary *properties)
{
    DbgPrint("init()\n");
    if (!BASE::init(properties))
    {
        ErrPrint("Couldn't init BASE\n");
        return false;
    }

    memset(&adapter_, 0, sizeof(at_adapter));
    adapter_.pdev = NULL;
    netIface_ = NULL;
    hw_addr_ = NULL;
    adapter_.pci_using_64 = false;
    adapter_.hw.mmr_base = NULL;
    adapter_.hw.back = &adapter_;
    return true;
}
Пример #13
0
void findEnd(Text_t *text, int* StringCount, size_t Textlen, int key)
{
	if (key == 1)
	{
		for (int i = 0; i < *StringCount; i++)
		{
			if (!text[i].StringPos)
				Nerror = STRPOSERR;
			assert(text[i].StringPos);
			ErrPrint(Nerror);

			if (text[i].StringPos[0] >= '1' && text[i].StringPos[0] <= '9')
				*StringCount = i;
		}
	}
	else
	{
		for (int i = 1; i < *StringCount; i++)
		{
			if (*(char*)text[i].StringPos - 3 >= '1' && *(char*)text[i].StringPos - 3 <= '9')
				*StringCount = i;
		}
	}
}
Пример #14
0
Text_t* InitText(int* StringCount, size_t *Textlen)
{
	setlocale(LC_ALL, "rus");
	FILE *filein;
	errno_t err = fopen_s(&filein, "input.txt", "rb");

	if (filein == NULL)
		Nerror = NOFILE;

	else
	{
		fseek(filein, 0, SEEK_END);
		*Textlen = ftell(filein);
		if (!(*Textlen)) perror("Ftell Error");
		rewind(filein);

		char *buffer = (char*)calloc(*Textlen + 1, sizeof(*buffer));
		assert(!buffer);
		if (buffer == NULL)
			Nerror = MEMERR;

		fread((char*)buffer, *Textlen, sizeof(*buffer), filein);
		if (buffer == 0) Nerror = FILEERR;
		ErrPrint(Nerror);
		if (fclose(filein) == -1) perror("Error with closing file\n");


		buffer[*Textlen] = '\0';

		*StringCount = 0;
		int i;
		for (i = 0; i <= (int)*Textlen; i++)
		{
			if (buffer[i] == '\r')
				*StringCount += 1;
			while (buffer[i] == '\r' || buffer[i] == '\n')
				i++;
		}

		Text_t *text = new Text_t[*StringCount + 1];

		assert(text);
		if (!text) Nerror = MEMERR;
		ErrPrint(Nerror);
		//perror("array of pointers was not create");

		int n = 0, nOld = 1;
		i = 1;
		while (buffer[n++] != '\r');
		(&text[0])->StringPos = buffer;
		(&text[0])->lenghtString = n - 1;
		n = n + 2;

		while (i < *StringCount)
		{
			int k = n;

			while (buffer[n] != '\r')
				n++;

			assert(0 <= i && i < *StringCount);
			if (!(0 <= i && i < *StringCount))
				Nerror = PTRERR;
			ErrPrint(Nerror);
			//perror("Asking for fail pointer");
			(&text[i])->StringPos = buffer + (k - 1)*sizeof(buffer[0]);
			(&text[i])->lenghtString = n - k + 1;
			i++;
			while (buffer[n] == '\r' || buffer[n] == '\n')
				n++;
			n = n + 1;
		}
		return text;
	}
	return NULL;
}
Пример #15
0
bool AtherosL1Ethernet::start(IOService *provider)
{
    DbgPrint("start()\n");

    at_adapter *adapter=&adapter_;
    
    if (!BASE::start(provider))
    {
        ErrPrint("Couldn't start BASE\n");
        return false;
    }

    adapter->pdev = OSDynamicCast(IOPCIDevice, provider);

    if (!adapter->pdev)
    {
        ErrPrint("Unable to cast provider\n");
        return false;
    }

    adapter->pdev->retain();
    adapter->pdev->open(this);

    //Adding Mac OS X PHY's
    mediumDict = OSDictionary::withCapacity(MEDIUM_INDEX_COUNT + 1);

    OSAddNetworkMedium(kIOMediumEthernetAuto, 0, MEDIUM_INDEX_AUTO);
    OSAddNetworkMedium(kIOMediumEthernet10BaseT | kIOMediumOptionHalfDuplex, 10 * MBit, MEDIUM_INDEX_10HD);
    OSAddNetworkMedium(kIOMediumEthernet10BaseT | kIOMediumOptionFullDuplex, 10 * MBit, MEDIUM_INDEX_10FD);
    OSAddNetworkMedium(kIOMediumEthernet100BaseTX | kIOMediumOptionHalfDuplex, 100 * MBit, MEDIUM_INDEX_100HD);
    OSAddNetworkMedium(kIOMediumEthernet100BaseTX | kIOMediumOptionFullDuplex, 100 * MBit, MEDIUM_INDEX_100FD);
    OSAddNetworkMedium(kIOMediumEthernet1000BaseTX | kIOMediumOptionHalfDuplex, 1000 * MBit, MEDIUM_INDEX_1000HD);
    OSAddNetworkMedium(kIOMediumEthernet1000BaseTX | kIOMediumOptionFullDuplex, 1000 * MBit, MEDIUM_INDEX_1000FD);
    
    if (!publishMediumDictionary(mediumDict)) return false;

    if (!atProbe()) //Fix false reporting int probe function
    {
        ErrPrint("Couldn't probe adapter\n");
        stop(provider);
        return false;
    }
    

    workLoop_ = getWorkLoop();
    if (!workLoop_)
    {
        ErrPrint("workLoop is not exists\n");
        stop(provider);
        return false;
    }

    transmitQueue_ = getOutputQueue();
    if (!transmitQueue_)
    {
        ErrPrint("transmitQueue is not exists\n");
        stop(provider);
        return false;
    }

    //Looking for MSI interrupt index
    int msi_index = -1;
    int intr_index = 0, intr_type = 0;
    IOReturn intr_ret;
    while (true)
    {
        intr_ret = provider->getInterruptType(intr_index, &intr_type);
        if (intr_ret != kIOReturnSuccess) break;
        if (intr_type & kIOInterruptTypePCIMessaged) msi_index = intr_index;
        intr_index++;
    }

    if (msi_index != -1)
    {
        DbgPrint("MSI interrupt index %d\n", msi_index);
        intSource_ = IOInterruptEventSource::interruptEventSource(this,
                    OSMemberFunctionCast(IOInterruptEventSource::Action, this, &AtherosL1Ethernet::atIntr),
                    adapter->pdev, msi_index);
    }

    if (msi_index == -1 || intSource_ == NULL)
    {
        DbgPrint("MSI index was not found or MSI interrupt couldn't be enabled\n");
        intSource_ = IOInterruptEventSource::interruptEventSource(this,
                    OSMemberFunctionCast(IOInterruptEventSource::Action, this, &AtherosL1Ethernet::atIntr),
                    adapter->pdev);
    }

    //Adding interrupt to our workloop event sources
    if (!intSource_ || workLoop_->addEventSource(intSource_) != kIOReturnSuccess)
    {
        if (!intSource_) ErrPrint("Couldn't create interrupt source\n");
        else ErrPrint("Couldn't attach interrupt source\n");
        stop(provider);
        return false;
    }

    //Attaching dynamic link layer
    if (!this->attachInterface(reinterpret_cast<IONetworkInterface **>(&netIface_)), false)
    {
        DbgPrint("Failed to attach data link layer\n");
        return false;
    }

    intSource_->enable();
    
    /* allocate Tx / RX descriptor resources */
    if (at_setup_ring_resources(adapter))
    {
        ErrPrint("Couldn't allocate ring descriptors\n");
        adapter->pdev->close(this);
        return kIOReturnError;
    }
    

    netIface_->registerService();
    adapter->pdev->close(this);
    return true;
}
Пример #16
0
/**
 * at_probe - Device Initialization Routine
 * @pdev: PCI device information struct
 * @ent: entry in at_pci_tbl
 *
 * Returns 0 on success, negative on failure
 *
 * at_probe initializes an adapter identified by a pci_dev structure.
 * The OS initialization, configuring of the adapter private structure,
 * and a hardware reset occur.
 **/
bool AtherosL1Ethernet::atProbe()
{
    u16  vendorId, deviceId;
    at_adapter *adapter=&adapter_;
    
    IOPCIDevice *pdev = adapter_.pdev;
    pdev->setBusMasterEnable(true);
    pdev->setMemoryEnable(true);
    pdev->setIOEnable(true);
    vendorId = pdev->configRead16(kIOPCIConfigVendorID);
    deviceId = pdev->configRead16(kIOPCIConfigDeviceID);

    DbgPrint("Vendor ID %x, device ID %x\n", vendorId, deviceId);
    DbgPrint("MMR0 address %x\n", (u32)pdev->configRead32(kIOPCIConfigBaseAddress0));

    pdev->enablePCIPowerManagement();

    hw_addr_ = pdev->mapDeviceMemoryWithRegister(kIOPCIConfigBaseAddress0);
    if (hw_addr_ == NULL)
    {
        ErrPrint("Couldn't map io regs\n");
        return false;
    }

    DbgPrint("Memory mapped at bus address %x, virtual address %x, length %d\n", (u32)hw_addr_->getPhysicalAddress(),
                    (u32)hw_addr_->getVirtualAddress(), (u32)hw_addr_->getLength());
    
    
    hw_addr_->retain();

    adapter->hw.mmr_base = reinterpret_cast<char *>(hw_addr_->getVirtualAddress());

    DbgPrint("REG_VPD_CAP = %x\n", OSReadLittleInt32(adapter->hw.mmr_base, REG_VPD_CAP));
    DbgPrint("REG_PCIE_CAP_LIST = %x\n", OSReadLittleInt32(adapter->hw.mmr_base, REG_PCIE_CAP_LIST));
    DbgPrint("REG_MASTER_CTRL = %x\n", OSReadLittleInt32(adapter->hw.mmr_base, REG_MASTER_CTRL));
    
    at_setup_pcicmd(pdev);
    
    /* get user settings */
    at_check_options(adapter);
    
    /* setup the private structure */
    if(at_sw_init(adapter))
    {
        ErrPrint("Couldn't init software\n");
        return false;
    }

    /* Init GPHY as early as possible due to power saving issue  */
    at_phy_init(&adapter->hw);

    /* reset the controller to 
     * put the device in a known good starting state */
    if (at_reset_hw(&adapter->hw))
    {
        ErrPrint("Couldn't reset hardware\n");
        return false;           //TO-DO: Uncomment
    }

    /* copy the MAC address out of the EEPROM */
    at_read_mac_addr(&adapter->hw);

    return true;
}
Пример #17
0
s32
at_setup_ring_resources(at_adapter *adapter)
{
    int size;
    u8 offset = 0;

    DEBUGFUNC("at_setup_ring_resources()\n");

    /* real ring DMA buffer */
    adapter->ring_size = size =   
	      adapter->txd_ring_size * 1   + 7         // dword align
	    + adapter->txs_ring_size * 4   + 7         // dword align
            + adapter->rxd_ring_size * 1536+ 127;    // 128bytes align
    
	adapter->memDesc = IOBufferMemoryDescriptor::withOptions(kIOMemoryPhysicallyContiguous|
																 kIODirectionOut|kIODirectionIn,
																	size,
																	PAGE_SIZE);
	DbgPrint("Allocated memory for ring header %d\n",size);

	if (!adapter->memDesc || (adapter->memDesc->prepare() != kIOReturnSuccess))
	{
		IOSleep(1500);
		ErrPrint("Couldn't alloc memory for descriptor ring\n");
		if (adapter->memDesc)
		{
			adapter->memDesc->release();
			adapter->memDesc = NULL;
		}
		DEBUGOUT1("Couldn't alloc memory for descriptor ring, size = D%d\n", size);
        return AT_ERR_ENOMEM;
	}

	IOByteCount dmaLength = 0;
	adapter->ring_dma = adapter->memDesc->getPhysicalSegment(0, &dmaLength);
	adapter->ring_vir_addr = adapter->memDesc->getBytesNoCopy();
	DbgPrint("ring Physical segment address %X pointer %p length %d\n",
			adapter->ring_dma, adapter->ring_vir_addr, dmaLength);

   
    
    memset(adapter->ring_vir_addr, 0, adapter->ring_size);

      // Init TXD Ring
      
      adapter->txd_dma = adapter->ring_dma ;
      offset = (adapter->txd_dma & 0x7) ? (8 - (adapter->txd_dma & 0x7)) : 0;
      adapter->txd_dma += offset;
      adapter->txd_ring = (tx_pkt_header_t*) ((u8*)adapter->ring_vir_addr + offset);
      
      // Init TXS Ring
      
      adapter->txs_dma = adapter->txd_dma + adapter->txd_ring_size;
      offset = (adapter->txs_dma & 0x7) ? (8- (adapter->txs_dma & 0x7)) : 0;
      adapter->txs_dma += offset;
      adapter->txs_ring = (tx_pkt_status_t*) 
                (((u8*)adapter->txd_ring) + (adapter->txd_ring_size+offset));
                
      // Init RXD Ring
      adapter->rxd_dma = adapter->txs_dma + adapter->txs_ring_size*4;
      offset = (adapter->rxd_dma & 127) ? (128 - (adapter->rxd_dma & 127)) : 0;
      if (offset > 7) {
	  offset -= 8;
      } else {
	  offset += (128 - 8);
      }
      adapter->rxd_dma += offset;
      adapter->rxd_ring = (rx_desc_t*)
                (((u8*)adapter->txs_ring) + 
		    (adapter->txs_ring_size*4 + offset));


      // Read / Write Ptr Initialize:
  //      init_ring_ptrs(adapter);

    return AT_SUCCESS;
}