#include <sys/types.h>
#include <sys/cmn_err.h>
#include <sys/debug.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
#include "amd8111s_hw.h"
#include "amd8111s_main.h"
static void mdlEnableMagicPacketWakeUp(struct LayerPointers *);
static void mdlAddWakeUpPattern(struct LayerPointers *, unsigned char *,
unsigned char *, unsigned long, unsigned long, int *);
static void mdlRemoveWakeUpPattern(struct LayerPointers *, unsigned char *,
unsigned long, int *);
static int mdlMulticastBitMapping(struct LayerPointers *, unsigned char *, int);
static unsigned int mdlCalculateCRC(unsigned int, unsigned char *);
static void mdlChangeFilter(struct LayerPointers *, unsigned long *);
static void mdlReceiveBroadCast(struct LayerPointers *);
static void mdlDisableReceiveBroadCast(struct LayerPointers *);
static void mdlRequestResources(ULONG *);
static void mdlSetResources(struct LayerPointers *, ULONG *);
static void mdlFreeResources(struct LayerPointers *, ULONG *);
static void
mdlInitGlbds(struct LayerPointers *pLayerPointers)
{
struct mdl *pMdl = pLayerPointers->pMdl;
pMdl->init_blk->MODE = 0x0000;
pMdl->IntrCoalescFlag = 1;
pMdl->rx_intrcoalesc_time = 0xC8;
pMdl->rx_intrcoalesc_events = 5;
}
void
mdlPHYAutoNegotiation(struct LayerPointers *pLayerPointers, unsigned int type)
{
int iData = 0;
struct mdl *pMdl = pLayerPointers->pMdl;
switch (type) {
case PHY_AUTO_NEGOTIATION:
WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD3, EN_PMGR);
drv_usecwait(100000);
WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CTRL2,
XPHYANE | XPHYRST);
WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD3,
VAL1 | EN_PMGR);
drv_usecwait(500000);
pMdl->Speed = 100;
pMdl->FullDuplex = B_TRUE;
break;
case PHY_FORCE_HD_100:
WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD3, EN_PMGR);
iData |= XPHYSP;
WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CTRL2, iData);
WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD3,
VAL1 | EN_PMGR);
drv_usecwait(500000);
pMdl->Speed = 100;
pMdl->FullDuplex = B_FALSE;
break;
case PHY_FORCE_FD_100:
WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD3, EN_PMGR);
iData |= (XPHYSP | XPHYFD);
WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CTRL2, iData);
WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD3,
VAL1 | EN_PMGR);
drv_usecwait(500000);
pMdl->Speed = 100;
pMdl->FullDuplex = B_TRUE;
break;
case PHY_FORCE_HD_10:
WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD3, EN_PMGR);
WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CTRL2, iData);
WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD3,
VAL1 | EN_PMGR);
drv_usecwait(500000);
pMdl->Speed = 10;
pMdl->FullDuplex = B_FALSE;
break;
case PHY_FORCE_FD_10:
WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD3, EN_PMGR);
iData |= XPHYFD;
WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CTRL2, iData);
WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD3,
VAL1 | EN_PMGR);
drv_usecwait(500000);
pMdl->Speed = 10;
pMdl->FullDuplex = B_TRUE;
break;
}
}
static void
mdlClearHWConfig(struct LayerPointers *pLayerPointers)
{
unsigned int data32;
int JumboFlag = JUMBO_DISABLED;
ULONG MemBaseAddress;
MemBaseAddress = pLayerPointers->pMdl->Mem_Address;
WRITE_REG16(pLayerPointers, MemBaseAddress + AUTOPOLL0, 0x8101);
WRITE_REG32(pLayerPointers, MemBaseAddress + RCV_RING_BASE_ADDR0, 0);
WRITE_REG32(pLayerPointers, MemBaseAddress + RCV_RING_BASE_ADDR1, 0);
WRITE_REG32(pLayerPointers, MemBaseAddress + RCV_RING_BASE_ADDR0, 0);
WRITE_REG32(pLayerPointers, MemBaseAddress + RCV_RING_BASE_ADDR2, 0);
WRITE_REG32(pLayerPointers, MemBaseAddress + RCV_RING_BASE_ADDR3, 0);
WRITE_REG32(pLayerPointers, MemBaseAddress + XMT_RING_BASE_ADDR0, 0);
WRITE_REG32(pLayerPointers, MemBaseAddress + XMT_RING_BASE_ADDR1, 0);
WRITE_REG32(pLayerPointers, MemBaseAddress + XMT_RING_BASE_ADDR2, 0);
WRITE_REG32(pLayerPointers, MemBaseAddress + XMT_RING_BASE_ADDR3, 0);
WRITE_REG32(pLayerPointers, MemBaseAddress + CMD0, 0x000F0F7F);
WRITE_REG32(pLayerPointers, MemBaseAddress + CMD2, 0x3F7F3F7F);
WRITE_REG32(pLayerPointers, MemBaseAddress + CMD3, VAL1 | EN_PMGR);
WRITE_REG32(pLayerPointers, MemBaseAddress + CMD7, 0x1B);
WRITE_REG32(pLayerPointers, MemBaseAddress + CTRL1, XMTSP_MASK);
WRITE_REG32(pLayerPointers, MemBaseAddress + DLY_INT_A, 0);
WRITE_REG32(pLayerPointers, MemBaseAddress + DLY_INT_B, 0);
WRITE_REG32(pLayerPointers, MemBaseAddress + FLOW_CONTROL, 0);
data32 = READ_REG32(pLayerPointers, MemBaseAddress + INT0);
WRITE_REG32(pLayerPointers, MemBaseAddress + INT0, data32);
WRITE_REG32(pLayerPointers, MemBaseAddress + STVAL, 0);
WRITE_REG32(pLayerPointers, MemBaseAddress + INTEN0, 0x1F7F7F1F);
WRITE_REG32(pLayerPointers, MemBaseAddress + LADRF1, 0);
WRITE_REG32(pLayerPointers, MemBaseAddress + LADRF1 + 4, 0);
WRITE_REG32(pLayerPointers, MemBaseAddress + LED0, 0);
WRITE_REG32(pLayerPointers, MemBaseAddress + LED1, 0);
WRITE_REG32(pLayerPointers, MemBaseAddress + LED2, 0);
WRITE_REG32(pLayerPointers, MemBaseAddress + LED3, 0);
WRITE_REG16(pLayerPointers, MemBaseAddress + RCV_RING_CFG, 1);
if (JumboFlag == JUMBO_ENABLED) {
WRITE_REG32(pLayerPointers, MemBaseAddress + SRAM_SIZE,
0xc0010);
} else {
WRITE_REG32(pLayerPointers, MemBaseAddress + SRAM_SIZE,
0x80010);
}
WRITE_REG32(pLayerPointers, MemBaseAddress + XMT_RING_LEN0, 0);
WRITE_REG32(pLayerPointers, MemBaseAddress + XMT_RING_LEN1, 0);
WRITE_REG32(pLayerPointers, MemBaseAddress + XMT_RING_LEN2, 0);
WRITE_REG32(pLayerPointers, MemBaseAddress + XMT_RING_LEN3, 0);
WRITE_REG32(pLayerPointers, MemBaseAddress + XMT_RING_LIMIT, 0);
WRITE_REG16(pLayerPointers, MemBaseAddress + MIB_ADDR, MIB_CLEAR);
}
unsigned int
mdlReadMib(struct LayerPointers *pLayerPointers, char MIB_COUNTER)
{
unsigned int status;
unsigned int data;
unsigned long mmio = pLayerPointers->pMdl->Mem_Address;
WRITE_REG16(pLayerPointers, mmio + MIB_ADDR, MIB_RD_CMD | MIB_COUNTER);
do {
status = READ_REG16(pLayerPointers, mmio + MIB_ADDR);
} while ((status & MIB_CMD_ACTIVE));
data = READ_REG32(pLayerPointers, mmio + MIB_DATA);
return (data);
}
unsigned int
mdlReadPHY(struct LayerPointers *pLayerPointers, unsigned char phyid,
unsigned char regaddr, unsigned int *value)
{
unsigned int status, data, count;
unsigned long mmio = pLayerPointers->pMdl->Mem_Address;
count = 0;
do {
status = READ_REG16(pLayerPointers, mmio + PHY_ACCESS);
count ++;
drv_usecwait(10);
} while ((status & PHY_CMD_ACTIVE) & (count < PHY_MAX_RETRY));
if (count == PHY_MAX_RETRY) {
return (0);
}
data = ((regaddr & 0x1f) << 16) | ((phyid & 0x1f) << 21) | PHY_RD_CMD;
WRITE_REG32(pLayerPointers, mmio + PHY_ACCESS, data);
do {
status = READ_REG16(pLayerPointers, mmio + PHY_ACCESS);
drv_usecwait(10);
count ++;
} while ((status & PHY_CMD_ACTIVE) & (count < PHY_MAX_RETRY));
if ((count == PHY_MAX_RETRY) || (status & PHY_RD_ERR)) {
return (0);
}
*value = status & 0xffff;
return (1);
}
void
mdlGetPHYID(struct LayerPointers *pLayerPointers)
{
unsigned int id1, id2, i;
for (i = 1; i < 32; i++) {
if (mdlReadPHY(pLayerPointers, i, MII_PHYSID1, &id1) == 0)
continue;
if (mdlReadPHY(pLayerPointers, i, MII_PHYSID2, &id2) == 0)
continue;
if ((id1 != 0xffff) & (id2 != 0xffff)) {
pLayerPointers->pMdl->phy_id = i;
return;
}
}
}
unsigned int
mdlWritePHY(struct LayerPointers *pLayerPointers, unsigned char phyid,
unsigned char regaddr, unsigned int value)
{
unsigned int status, data, count;
unsigned long mmio = pLayerPointers->pMdl->Mem_Address;
count = 0;
do {
status = READ_REG16(pLayerPointers, mmio + PHY_ACCESS);
count ++;
drv_usecwait(10);
} while ((status & PHY_CMD_ACTIVE) & (count < PHY_MAX_RETRY));
if (count == PHY_MAX_RETRY) {
return (0);
}
data = ((regaddr & 0x1f) << 16) | ((phyid & 0x1f) << 21) |
(value & 0xffff) | PHY_WR_CMD;
WRITE_REG32(pLayerPointers, mmio + PHY_ACCESS, data);
do {
status = READ_REG16(pLayerPointers, mmio + PHY_ACCESS);
drv_usecwait(10);
count ++;
} while ((status & PHY_CMD_ACTIVE) & (count < PHY_MAX_RETRY));
if ((count == PHY_MAX_RETRY) && (status & PHY_RD_ERR)) {
return (0);
}
return (1);
}
void
mdlTransmit(struct LayerPointers *pLayerPointers)
{
WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address + CMD0,
VAL1 | TDMD0);
}
void
mdlReceive(struct LayerPointers *pLayerPointers)
{
WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address + CMD0,
VAL2 | RDMD0);
}
unsigned int
mdlReadInterrupt(struct LayerPointers *pLayerPointers)
{
unsigned int nINT0;
struct mdl *pMdl = 0;
pMdl = (struct mdl *)(pLayerPointers->pMdl);
nINT0 = READ_REG32(pLayerPointers, pMdl->Mem_Address + INT0);
WRITE_REG32(pLayerPointers, pMdl->Mem_Address + INT0, nINT0);
return (nINT0);
}
void
mdlHWReset(struct LayerPointers *pLayerPointers)
{
struct mdl *pMdl = pLayerPointers->pMdl;
unsigned int ulData, i = 0;
int JumboFlag = JUMBO_DISABLED;
ULONG Mem_Address = pMdl->Mem_Address;
mdlStopChip(pLayerPointers);
for (i = 0; i < ETH_LENGTH_OF_ADDRESS; i++) {
WRITE_REG8(pLayerPointers, pMdl->Mem_Address + PADR + i,
pMdl->Mac[i]);
}
if (JumboFlag == JUMBO_ENABLED) {
WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD2,
VAL0 | APAD_XMT | REX_RTRY | VAL1 | DXMTFCS | RPA | VAL2);
WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD3,
VAL2 | JUMBO);
} else {
WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD2,
VAL0 | APAD_XMT | REX_RTRY | REX_UFLO | VAL1 | DXMTFCS
| ASTRIP_RCV | RPA | VAL2);
}
ulData = READ_REG32(pLayerPointers, Mem_Address + CTRL1);
ulData &= ~XMTSP_MASK;
WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CTRL1,
ulData | XMTSP_128);
WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD2, PROM);
mdlPHYAutoNegotiation(pLayerPointers, pMdl->External_Phy);
pMdl->IpgValue = MIN_IPG_DEFAULT;
WRITE_REG16(pLayerPointers, pMdl->Mem_Address + IFS,
pMdl->IpgValue);
WRITE_REG32(pLayerPointers, pMdl->Mem_Address + INTEN0,
APINT5EN | APINT4EN | APINT3EN |
APINT2EN | APINT1EN | APINT0EN | MIIPDTINTEN |
MCCIINTEN | MCCINTEN | MREINTEN |
TINTEN0 |
SPNDINTEN | MPINTEN | SINTEN | LCINTEN);
WRITE_REG32(pLayerPointers, pMdl->Mem_Address + INTEN0,
VAL0 | RINTEN0);
WRITE_REG32(pLayerPointers, pMdl->Mem_Address + XMT_RING_BASE_ADDR0,
pMdl->init_blk->TDRA);
WRITE_REG32(pLayerPointers, pMdl->Mem_Address + RCV_RING_BASE_ADDR0,
pMdl->init_blk->RDRA);
WRITE_REG16(pLayerPointers, pMdl->Mem_Address + XMT_RING_LEN0,
(unsigned short)pLayerPointers->pMdl->TxRingSize);
WRITE_REG16(pLayerPointers, pMdl->Mem_Address + RCV_RING_LEN0,
(unsigned short)pLayerPointers->pMdl->RxRingSize);
if (pLayerPointers->pMdl->IntrCoalescFlag) {
SetIntrCoalesc(pLayerPointers, B_TRUE);
}
mdlStartChip(pLayerPointers);
}
void
mdlOpen(struct LayerPointers *pLayerPointers)
{
int i, sum;
struct mdl *pMdl = pLayerPointers->pMdl;
sum = 0;
for (i = 0; i < 6; i++) {
pMdl->Mac[i] = READ_REG8(pLayerPointers,
pMdl->Mem_Address + PADR + i);
sum += pMdl->Mac[i];
}
if (sum == 0) {
for (i = 0; i < 6; i++) {
pMdl->Mac[i] = 0;
}
}
mdlClearHWConfig(pLayerPointers);
mdlGetPHYID(pLayerPointers);
}
void
mdlGetMacAddress(struct LayerPointers *pLayerPointers,
unsigned char *macAddress)
{
struct mdl *pMdl = pLayerPointers->pMdl;
int i;
for (i = 0; i < 6; i++) {
macAddress[i] = pMdl->Mac[i] = READ_REG8(pLayerPointers,
pMdl->Mem_Address + PADR + i);
}
}
void
mdlSetMacAddress(struct LayerPointers *pLayerPointers,
unsigned char *macAddress)
{
int i;
struct mdl *pMdl = 0;
pMdl = (struct mdl *)(pLayerPointers->pMdl);
pMdl->Mac[0] = macAddress[0];
pMdl->Mac[1] = macAddress[1];
pMdl->Mac[2] = macAddress[2];
pMdl->Mac[3] = macAddress[3];
pMdl->Mac[4] = macAddress[4];
pMdl->Mac[5] = macAddress[5];
for (i = 0; i < ETH_LENGTH_OF_ADDRESS; i++) {
WRITE_REG8(pLayerPointers, pMdl->Mem_Address + PADR + i,
pMdl->Mac[i]);
}
}
static void
mdlRequestResources(ULONG *mem_req_array)
{
*mem_req_array = VIRTUAL;
*(++mem_req_array) = sizeof (struct mdl);
*(++mem_req_array) = VIRTUAL;
*(++mem_req_array) = sizeof (unsigned int) * (MAX_ALLOWED_PATTERNS + 2);
*(++mem_req_array) = VIRTUAL;
*(++mem_req_array) = sizeof (unsigned char) * (MAX_PATTERNS + 2);
*(++mem_req_array) = VIRTUAL;
*(++mem_req_array) = sizeof (unsigned int) * (MAX_ALLOWED_PATTERNS + 2);
*(++mem_req_array) = VIRTUAL;
*(++mem_req_array) = sizeof (struct init_block);
*(++mem_req_array) = 0;
mem_req_array++;
}
static void
mdlSetResources(struct LayerPointers *pLayerPointers, ULONG *pmem_set_array)
{
struct mdl *pMdl = 0;
pmem_set_array++;
pmem_set_array++;
pLayerPointers->pMdl = (struct mdl *)(*pmem_set_array);
pMdl = (struct mdl *)(pLayerPointers->pMdl);
pMdl->RxRingLenBits = RX_RING_LEN_BITS;
pMdl->TxRingLenBits = TX_RING_LEN_BITS;
pMdl->TxRingSize = TX_RING_SIZE;
pMdl->RxRingSize = RX_RING_SIZE;
pmem_set_array++;
pmem_set_array++;
pmem_set_array++;
pMdl->PMR_PtrList = (unsigned int *)(*pmem_set_array);
pmem_set_array++;
pmem_set_array++;
pmem_set_array++;
pMdl->PatternList = (unsigned char *)(*pmem_set_array);
pmem_set_array++;
pmem_set_array++;
pmem_set_array++;
pMdl->PatternLength = (unsigned int *)(*pmem_set_array);
pmem_set_array++;
pmem_set_array++;
pmem_set_array++;
pMdl->init_blk = (struct init_block *)(*pmem_set_array);
pMdl->init_blk->TLEN = pMdl->TxRingLenBits;
pMdl->init_blk->RLEN = pMdl->RxRingLenBits;
pmem_set_array++;
*pmem_set_array = 0;
}
static void
mdlFreeResources(struct LayerPointers *pLayerPointers, ULONG *pmem_free_array)
{
struct mdl *pMdl = 0;
pMdl = (struct mdl *)(pLayerPointers->pMdl);
*(pmem_free_array) = VIRTUAL;
*(++pmem_free_array) = sizeof (struct mdl);
*(++pmem_free_array) = (ULONG)pMdl;
*(++pmem_free_array) = VIRTUAL;
*(++pmem_free_array) = sizeof (unsigned int)
* (MAX_ALLOWED_PATTERNS + 2);
*(++pmem_free_array) = (ULONG)pMdl->PMR_PtrList;
*(++pmem_free_array) = VIRTUAL;
*(++pmem_free_array) = sizeof (unsigned char) * (MAX_PATTERNS + 2);
*(++pmem_free_array) = (ULONG)pMdl->PatternList;
*(++pmem_free_array) = VIRTUAL;
*(++pmem_free_array) = sizeof (unsigned int)
* (MAX_ALLOWED_PATTERNS + 2);
*(++pmem_free_array) = (ULONG)pMdl->PatternLength;
*(++pmem_free_array) = VIRTUAL;
*(++pmem_free_array) = sizeof (struct init_block);
*(++pmem_free_array) = (ULONG)pMdl->init_blk;
*(++pmem_free_array) = 0;
}
void
mdlStartChip(struct LayerPointers *pLayerPointers)
{
WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address + CMD0,
VAL2 | RDMD0);
WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address + CMD0,
VAL0 | INTREN | RUN);
}
void
mdlStopChip(struct LayerPointers *pLayerPointers)
{
int nINT0;
struct mdl *pMdl = 0;
pMdl = (struct mdl *)(pLayerPointers->pMdl);
WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD0, INTREN);
nINT0 = READ_REG32(pLayerPointers, pMdl->Mem_Address + INT0);
WRITE_REG32(pLayerPointers, pMdl->Mem_Address + INT0, nINT0);
WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD0, RUN);
}
void
mdlEnableInterrupt(struct LayerPointers *pLayerPointers)
{
WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address + CMD0,
VAL0 | INTREN);
}
#ifdef AMD8111S_DEBUG
static void
mdlClearInterrupt(struct LayerPointers *pLayerPointers)
{
unsigned int nINT0;
struct mdl *pMdl = 0;
pMdl = (struct mdl *)(pLayerPointers->pMdl);
nINT0 = READ_REG32(pLayerPointers, pMdl->Mem_Address + INT0);
WRITE_REG32(pLayerPointers, pMdl->Mem_Address + INT0, nINT0);
}
#endif
void
mdlDisableInterrupt(struct LayerPointers *pLayerPointers)
{
WRITE_REG32(pLayerPointers,
pLayerPointers->pMdl->Mem_Address + CMD0, INTREN);
}
int
mdlReadLink(struct LayerPointers *pLayerPointers)
{
unsigned int link_status = 0;
link_status = READ_REG32(pLayerPointers,
pLayerPointers->pMdl->Mem_Address + STAT0);
if ((link_status & LINK_STAT)) {
return (LINK_UP);
} else {
return (LINK_DOWN);
}
}
static void
mdlAddWakeUpPattern(struct LayerPointers *pLayerPointers,
unsigned char *PatternMask, unsigned char *Pattern,
unsigned long InfoBuffer_MaskSize, unsigned long PatternSize, int *retval)
{
unsigned long MaskSize;
unsigned long ReqSize;
unsigned char byteData = 0, tmpData;
unsigned char Skip = 0;
unsigned int i = 0, flag = 1, count = 1;
unsigned int j;
int PatternOffset, SearchForStartOfPattern = 1;
struct mdl *pMdl = 0;
pMdl = pLayerPointers->pMdl;
if (pMdl->TotalPatterns >= MAX_ALLOWED_PATTERNS) {
*retval = -1;
return;
}
MaskSize = PatternSize/4 + (PatternSize%4 ? 1 : 0);
ReqSize = PatternSize + MaskSize;
if (((PatternSize+MaskSize)%5) != 0)
ReqSize += 5 - ((PatternSize+MaskSize)%5);
if (ReqSize >
(unsigned long)(MAX_PATTERNS - pMdl->PatternList_FreeIndex)) {
*retval = -1;
return;
}
if (InfoBuffer_MaskSize != PatternSize/8 + (PatternSize%8 ? 1 : 0)) {
*retval = -1;
return;
}
i = pMdl->PatternList_FreeIndex;
pMdl->PMR_PtrList[pMdl->TotalPatterns] = i;
pMdl->PatternLength[pMdl->TotalPatterns] = (unsigned int)PatternSize;
while (i < (pMdl->PatternList_FreeIndex + PatternSize + MaskSize)) {
if (flag) {
byteData = *PatternMask;
pMdl->PatternList[i++] =
(unsigned int)((byteData & 0x0F) | (Skip<< 4));
flag = 0;
} else {
pMdl->PatternList[i++] = (unsigned int)
(((unsigned)(byteData & 0xF0) >> 4) | (Skip << 4));
PatternMask++;
flag = 1;
}
count = 1;
while ((count < 5) && (i <
pMdl->PatternList_FreeIndex + PatternSize + MaskSize)) {
tmpData = *Pattern;
Pattern++;
pMdl->PatternList[i++] = tmpData;
count++;
}
}
for (i = (pMdl->PatternList_FreeIndex + PatternSize + MaskSize);
i < (pMdl->PatternList_FreeIndex + ReqSize); i++)
pMdl->PatternList[i] = 0;
pMdl->PatternList[pMdl->PatternList_FreeIndex + ReqSize - 5] |= 0x80;
for (j = 0; j < 8; j++) {
pMdl->tmpPtrArray[j] = 0;
}
j = 0;
while (j < (pMdl->PatternList_FreeIndex + ReqSize)) {
pMdl->PatternList[j] &= 0x8f;
j += 5;
}
j = 0;
i = 0;
PatternOffset = 1;
Skip = 0;
while (j < (pMdl->PatternList_FreeIndex + ReqSize)) {
if (pMdl->PatternList[j] & 0x0f) {
PatternOffset ++;
if (SearchForStartOfPattern == 1) {
SearchForStartOfPattern = 0;
pMdl->tmpPtrArray[i++] = PatternOffset;
} else if (pMdl->PatternList[j] & 0x80) {
SearchForStartOfPattern = 1;
}
pMdl->PatternList[j] |= (Skip << 4);
Skip = 0;
} else {
Skip++;
}
j += 5;
}
pMdl->PatternList_FreeIndex += (unsigned short)ReqSize;
pMdl->TotalPatterns++;
*retval = 0;
}
static void
mdlRemoveWakeUpPattern(struct LayerPointers *pLayerPointers,
unsigned char *Pattern, unsigned long PatternSize, int *retval)
{
unsigned long ReqSize, MaskSize;
unsigned char tmpData;
unsigned long Data;
unsigned short Data1, Data2, Data3, Data4, Data5, Data6, Data7, Data8;
int PatternMismatch = 0;
int count, StartIndex, index = 0;
unsigned int i, j;
unsigned char Skip = 0;
struct mdl *pMdl = 0;
int PatternOffset, SearchForStartOfPattern = 1;
unsigned long tmpPtrArray[8];
int offset;
Data1 = Data2 = Data3 = Data4 = Data5 = Data6 = Data7 = Data8 = 0;
pMdl = (struct mdl *)(pLayerPointers->pMdl);
if (pMdl->TotalPatterns == 0) {
*retval = -1;
return;
}
MaskSize = PatternSize/4 + (PatternSize%4 ? 1 : 0);
ReqSize = PatternSize + MaskSize;
if (((PatternSize+MaskSize)%5) != 0)
ReqSize += 5 - ((PatternSize+MaskSize)%5);
count = pMdl->TotalPatterns;
while (count--) {
PatternMismatch = 0;
StartIndex = pMdl->PMR_PtrList[index];
if (pMdl->PatternLength[index] != PatternSize) {
index++;
PatternMismatch = 1;
continue;
}
for (i = StartIndex; i < (StartIndex+ReqSize); i++) {
if (!(i%5))
i++;
tmpData = *Pattern;
if (pMdl->PatternList[i] != tmpData) {
PatternMismatch = 1;
break;
}
Pattern++;
}
if (PatternMismatch == 0) {
i = StartIndex + ReqSize;
while (i < pMdl->PatternList_FreeIndex) {
pMdl->PatternList[StartIndex] =
pMdl->PatternList[i];
i++;
StartIndex++;
}
pMdl->PatternList_FreeIndex =
(unsigned short)(StartIndex);
while (StartIndex < MAX_PATTERNS)
pMdl->PatternList[StartIndex++] = 0;
while (index < (int)pMdl->TotalPatterns) {
pMdl->PMR_PtrList[index] =
pMdl->PMR_PtrList[index+1] - ReqSize;
pMdl->PatternLength[index] =
pMdl->PatternLength[index+1];
index ++;
}
index--;
while (index < MAX_ALLOWED_PATTERNS) {
pMdl->PMR_PtrList[index+1] = 0;
pMdl->PatternLength[index+1] = 0;
index++;
}
break;
}
index++;
}
if (PatternMismatch) {
*retval = -1;
return;
}
for (j = 0; j < 8; j++) {
tmpPtrArray[j] = 0;
}
j = 0;
while (j < (pMdl->PatternList_FreeIndex)) {
pMdl->PatternList[j] &= 0x8f;
j += 5;
}
j = 0;
i = 0;
Skip = 0;
PatternOffset = 1;
while (j < (pMdl->PatternList_FreeIndex)) {
if (pMdl->PatternList[j] & 0x0f) {
PatternOffset++;
if (SearchForStartOfPattern == 1) {
SearchForStartOfPattern = 0;
tmpPtrArray[i++] = PatternOffset;
} else if (pMdl->PatternList[j] & 0x80) {
SearchForStartOfPattern = 1;
}
pMdl->PatternList[j] |= (Skip << 4);
Skip = 0;
} else {
Skip++;
}
j += 5;
}
WRITE_REG32(pLayerPointers, pMdl->Mem_Address+CMD7, PMAT_MODE);
i = 0;
offset = 2;
while (i < MAX_PATTERNS) {
if (pMdl->PatternList[i] != 0) {
Data = pMdl->PatternList[i+3] << 24 |
pMdl->PatternList[i+2] << 16 |
pMdl->PatternList[i+1] << 8 |
pMdl->PatternList[i];
WRITE_REG32(pLayerPointers,
pMdl->Mem_Address+PMAT1, Data);
Data = (unsigned long) ((1<<30) | (offset << 16) |
pMdl->PatternList[i+4]);
WRITE_REG32(pLayerPointers,
pMdl->Mem_Address+PMAT0, Data);
offset++;
if (offset >= 64) {
*retval = -1;
return;
}
}
i += 5;
}
pMdl->TotalPatterns--;
pMdl->PatternEnableBit = 0;
for (i = 0; i < pMdl->TotalPatterns; i++) {
pMdl->PatternEnableBit |= (0x0001 << i);
}
Data1 = Data2 = Data3 = Data4 = Data5 = Data6 = Data7 = Data8 = 0;
switch (pMdl->TotalPatterns) {
case 8 :
Data8 = (unsigned short)tmpPtrArray[7];
case 7 :
Data7 = (unsigned short)tmpPtrArray[6];
case 6 :
Data6 = (unsigned short)tmpPtrArray[5];
case 5 :
Data5 = (unsigned short)tmpPtrArray[4];
case 4 :
Data4 = (unsigned short)tmpPtrArray[3];
case 3 :
Data3 = (unsigned short)tmpPtrArray[2];
case 2 :
Data2 = (unsigned short)tmpPtrArray[1];
case 1 :
Data1 = (unsigned short)tmpPtrArray[0];
break;
}
Data = pMdl->PatternEnableBit & 0x0f;
Data = (Data3 << 24 | Data2 << 16 | Data1 << 8 | Data);
WRITE_REG32(pLayerPointers, pMdl->Mem_Address + PMAT1, Data);
Data = (unsigned long) ((1<<30) | Data4);
WRITE_REG32(pLayerPointers, pMdl->Mem_Address + PMAT0, Data);
Data = (unsigned short)((unsigned)(pMdl->PatternEnableBit & 0xf0) >> 4);
Data = (Data7 << 24 | Data6 << 16 | Data5 << 8 | Data);
WRITE_REG32(pLayerPointers, pMdl->Mem_Address + PMAT1, Data);
Data = (unsigned long) ((1<<30) | (1<<16) | Data8);
WRITE_REG32(pLayerPointers, pMdl->Mem_Address + PMAT0, Data);
WRITE_REG32(pLayerPointers, pMdl->Mem_Address + CMD7, VAL0 | PMAT_MODE);
*retval = 0;
}
void
mdlGetActiveMediaInfo(struct LayerPointers *pLayerPointers)
{
unsigned long ulData;
struct mdl *pMdl = 0;
pMdl = (struct mdl *)(pLayerPointers->pMdl);
ulData = READ_REG32(pLayerPointers, pMdl->Mem_Address + STAT0);
switch (ulData & SPEED_MASK) {
case SPEED_100Mbps:
pMdl->Speed = 100;
break;
case SPEED_10Mbps:
pMdl->Speed = 10;
break;
default:
pMdl->Speed = 100;
break;
}
if (ulData & FULL_DPLX) {
pMdl->FullDuplex = B_TRUE;
} else {
pMdl->FullDuplex = B_FALSE;
}
}
void
mdlChangeFilter(struct LayerPointers *pLayerPointers, unsigned long *ArrayPtr)
{
unsigned long *Ptr;
unsigned char *MulticastArray;
unsigned char *Pattern, *PatternMask;
unsigned int InfoBuffer_MaskSize, PatternSize;
int *retval;
int NumberOfAddress, i;
unsigned int j, CRCValue = 0;
unsigned char HashCode = 0, FilterByte = 0;
int BitMapIndex = 0;
Ptr = ArrayPtr;
while (*Ptr) {
switch (*Ptr) {
case DISABLE_BROADCAST:
mdlDisableReceiveBroadCast(pLayerPointers);
break;
case ENABLE_BROADCAST:
mdlReceiveBroadCast(pLayerPointers);
break;
case ENABLE_ALL_MULTICAST:
for (i = 0; i < 8; i++) {
pLayerPointers->pMdl->init_blk->LADRF[i] = 0xff;
}
WRITE_REG64(pLayerPointers,
(unsigned long)pLayerPointers->pMdl
->Mem_Address + LADRF1,
(char *)pLayerPointers->pMdl->init_blk->LADRF);
break;
case DISABLE_ALL_MULTICAST:
if (pLayerPointers->pMdl->EnableMulticast == 1) {
for (i = 0; i < 8; i++) {
pLayerPointers->pMdl->init_blk
->LADRF[i] =
pLayerPointers->pMdl->TempLADRF[i];
}
}
WRITE_REG64(pLayerPointers,
(unsigned long)pLayerPointers->pMdl->Mem_Address
+ LADRF1,
(char *)pLayerPointers->pMdl->init_blk->LADRF);
break;
case ADD_MULTICAST:
NumberOfAddress = *(++Ptr);
MulticastArray = (unsigned char *)(*(++Ptr));
mdlAddMulticastAddresses(pLayerPointers,
NumberOfAddress, MulticastArray);
break;
case ENABLE_MULTICAST:
for (i = 0; i < 8; i++) {
pLayerPointers->pMdl->init_blk->LADRF[i] =
pLayerPointers->pMdl->TempLADRF[i];
}
pLayerPointers->pMdl->EnableMulticast = 1;
WRITE_REG64(pLayerPointers,
(unsigned long)pLayerPointers->pMdl->Mem_Address
+ LADRF1,
(char *)pLayerPointers->pMdl->init_blk->LADRF);
break;
case DISABLE_MULTICAST:
for (i = 0; i < 8; i++) {
pLayerPointers->pMdl->init_blk->LADRF[i] = 0;
}
pLayerPointers->pMdl->EnableMulticast = 0;
for (BitMapIndex = 0; BitMapIndex <
MULTICAST_BITMAP_ARRAY_SIZE; BitMapIndex++)
pLayerPointers->pMdl->MulticastBitMapArray
[BitMapIndex] = 0;
WRITE_REG64(pLayerPointers,
(unsigned long)pLayerPointers->pMdl->Mem_Address
+ LADRF1,
(char *)pLayerPointers->pMdl->init_blk->LADRF);
break;
case ADD_WAKE_UP_PATTERN:
PatternMask = (unsigned char *)(*(++Ptr));
Pattern = (unsigned char *)(*(++Ptr));
InfoBuffer_MaskSize = (*(++Ptr));
PatternSize = (*(++Ptr));
retval = (int *)(*(++Ptr));
mdlAddWakeUpPattern(pLayerPointers,
PatternMask,
Pattern,
InfoBuffer_MaskSize,
PatternSize,
retval);
break;
case REMOVE_WAKE_UP_PATTERN:
Pattern = (unsigned char *)(*(++Ptr));
PatternSize = *(++Ptr);
retval = (int *)(*(++Ptr));
mdlRemoveWakeUpPattern(pLayerPointers,
Pattern,
PatternSize,
retval);
break;
case ENABLE_MAGIC_PACKET_WAKE_UP:
mdlEnableMagicPacketWakeUp(pLayerPointers);
break;
case SET_SINGLE_MULTICAST:
NumberOfAddress = *(++Ptr);
MulticastArray = (unsigned char *)(*(++Ptr));
for (i = 0; i < 8; i++) {
pLayerPointers->pMdl->TempLADRF[i] =
pLayerPointers->pMdl->init_blk->LADRF[i];
}
CRCValue = mdlCalculateCRC(ETH_LENGTH_OF_ADDRESS,
MulticastArray);
for (j = 0; j < 6; j++) {
HashCode = (HashCode << 1) +
(((unsigned char)CRCValue >> j) & 0x01);
}
FilterByte = HashCode >> 3;
pLayerPointers->pMdl->TempLADRF[FilterByte] |=
(1 << (HashCode & 0x07));
break;
case UNSET_SINGLE_MULTICAST:
NumberOfAddress = *(++Ptr);
MulticastArray = (unsigned char *)(*(++Ptr));
for (i = 0; i < 8; i++) {
pLayerPointers->pMdl->TempLADRF[i] =
pLayerPointers->pMdl->init_blk->LADRF[i];
}
CRCValue = mdlCalculateCRC(ETH_LENGTH_OF_ADDRESS,
MulticastArray);
for (j = 0; j < 6; j++) {
HashCode = ((HashCode << 1) +
(((unsigned char)CRCValue >> j) & 0x01));
}
FilterByte = HashCode >> 3;
pLayerPointers->pMdl->TempLADRF[FilterByte] &=
~(1 << (HashCode & 0x07));
break;
default:
break;
}
Ptr++;
}
}
void
mdlAddMulticastAddresses(struct LayerPointers *pLayerPointers,
int NumberOfAddress, unsigned char *MulticastAddresses)
{
unsigned int j, CRCValue;
unsigned char HashCode, FilterByte;
int i;
for (i = 0; i < 8; i++) {
pLayerPointers->pMdl->TempLADRF[i] = 0x00;
}
for (i = 0; i < NumberOfAddress; i++) {
HashCode = 0;
CRCValue = mdlCalculateCRC(ETH_LENGTH_OF_ADDRESS,
MulticastAddresses);
for (j = 0; j < 6; j++) {
HashCode = (HashCode << 1) +
(((unsigned char)CRCValue >> j) & 0x01);
}
FilterByte = HashCode >> 3;
pLayerPointers->pMdl->TempLADRF[FilterByte] |=
(1 << (HashCode & 0x07));
MulticastAddresses += ETH_LENGTH_OF_ADDRESS;
}
}
void
mdlSetPromiscuous(struct LayerPointers *pLayerPointers)
{
WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address + CMD2,
VAL2 | PROM);
pLayerPointers->pMdl->FLAGS |= PROM;
}
void
mdlDisablePromiscuous(struct LayerPointers *pLayerPointers)
{
WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address + CMD2,
PROM);
pLayerPointers->pMdl->FLAGS &= (~ PROM);
}
static void
mdlReceiveBroadCast(struct LayerPointers *pLayerPointers)
{
ULONG MappedMemBaseAddress;
MappedMemBaseAddress = pLayerPointers->pMdl->Mem_Address;
WRITE_REG32(pLayerPointers, MappedMemBaseAddress + CMD2, DRCVBC);
pLayerPointers->pMdl->FLAGS |= DRCVBC;
}
static void
mdlDisableReceiveBroadCast(struct LayerPointers *pLayerPointers)
{
ULONG MappedMemBaseAddress;
MappedMemBaseAddress = pLayerPointers->pMdl->Mem_Address;
WRITE_REG32(pLayerPointers, MappedMemBaseAddress + CMD2, VAL2 | DRCVBC);
pLayerPointers->pMdl->FLAGS &= (~DRCVBC);
}
static void
mdlEnableMagicPacketWakeUp(struct LayerPointers *pLayerPointers)
{
WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address + CMD3,
VAL1 | MPPLBA);
WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address + CMD7,
VAL0 | MPEN_SW);
}
static int
mdlMulticastBitMapping(struct LayerPointers *pLayerPointers,
unsigned char *MulticastAddress, int FLAG)
{
unsigned char HashCode, FilterByte;
int j = 0, BitMapIndex = 0;
unsigned int CRCValue = 0;
HashCode = 0;
CRCValue = mdlCalculateCRC(ETH_LENGTH_OF_ADDRESS, MulticastAddress);
for (j = 0; j < 6; j++) {
HashCode = (HashCode << 1) +
(((unsigned char)CRCValue >> j) & 0x01);
}
FilterByte = HashCode & 0x38;
FilterByte = FilterByte >> 3;
BitMapIndex = (int)FilterByte * 8 + (HashCode & 0x7);
if (FLAG == DELETE_MULTICAST) {
if ((pLayerPointers->pMdl->MulticastBitMapArray[BitMapIndex]
== 0) || (--pLayerPointers->pMdl->MulticastBitMapArray
[BitMapIndex] == 0)) {
return (0);
} else {
return (-1);
}
}
if (FLAG == ADD_MULTICAST) {
if (pLayerPointers->pMdl
->MulticastBitMapArray[BitMapIndex] > 0) {
pLayerPointers->pMdl
->MulticastBitMapArray[BitMapIndex]++;
return (-1);
} else if (pLayerPointers->pMdl
->MulticastBitMapArray[BitMapIndex] == 0) {
pLayerPointers->pMdl
->MulticastBitMapArray[BitMapIndex]++;
return (0);
}
}
return (0);
}
void
SetIntrCoalesc(struct LayerPointers *pLayerPointers, boolean_t on)
{
long MemBaseAddress = pLayerPointers->pMdl->Mem_Address;
struct mdl *pMdl = 0;
unsigned int timeout, event_count;
pMdl = (struct mdl *)(pLayerPointers->pMdl);
if (on) {
timeout = pLayerPointers->pMdl->rx_intrcoalesc_time;
event_count = 0;
event_count |= pLayerPointers->pMdl->rx_intrcoalesc_events;
if (timeout > 0x7ff) {
timeout = 0x7ff;
}
if (event_count > 0x1f) {
event_count = 0x1f;
}
event_count = event_count << 16;
WRITE_REG32(pLayerPointers, MemBaseAddress + DLY_INT_A,
DLY_INT_A_R0 | event_count | timeout);
} else {
WRITE_REG32(pLayerPointers, MemBaseAddress + STVAL, 0);
WRITE_REG32(pLayerPointers, pMdl->Mem_Address + INTEN0,
STINTEN);
WRITE_REG32(pLayerPointers, MemBaseAddress + DLY_INT_A, 0);
WRITE_REG32(pLayerPointers, MemBaseAddress + DLY_INT_B, 0);
}
}
void
mdlSendPause(struct LayerPointers *pLayerPointers)
{
WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address
+ FLOW_CONTROL, VAL2 | FIXP | FCCMD | 0x200);
}
void
milResetTxQ(struct LayerPointers *pLayerPointers)
{
struct nonphysical *pNonphysical = pLayerPointers->pMil->pNonphysical;
int i;
pNonphysical->TxDescQRead = pNonphysical->TxDescQStart;
pNonphysical->TxDescQWrite = pNonphysical->TxDescQStart;
for (i = 0; i < TX_RING_SIZE; i++) {
pNonphysical->TxDescQWrite->Tx_OWN = 0;
pNonphysical->TxDescQWrite->Tx_SOP = 0;
pNonphysical->TxDescQWrite->Tx_EOP = 0;
pNonphysical->TxDescQWrite++;
}
pNonphysical->TxDescQWrite = pNonphysical->TxDescQStart;
pLayerPointers->pOdl->tx_buf.free =
pLayerPointers->pOdl->tx_buf.msg_buf;
pLayerPointers->pOdl->tx_buf.next =
pLayerPointers->pOdl->tx_buf.msg_buf;
pLayerPointers->pOdl->tx_buf.curr =
pLayerPointers->pOdl->tx_buf.msg_buf;
}
void
milInitGlbds(struct LayerPointers *pLayerPointers)
{
pLayerPointers->pMil->name = DEVICE_CHIPNAME;
mdlInitGlbds(pLayerPointers);
}
void
milInitRxQ(struct LayerPointers *pLayerPointers)
{
struct mil *pMil = pLayerPointers->pMil;
struct nonphysical *pNonphysical = pMil->pNonphysical;
int i;
pNonphysical->RxBufDescQRead->descriptor = pMil->Rx_desc;
pNonphysical->RxBufDescQStart->descriptor = pMil->Rx_desc;
pNonphysical->RxBufDescQEnd->descriptor =
&(pMil->Rx_desc[pMil->RxRingSize - 1]);
pNonphysical->RxBufDescQRead->USpaceMap = pMil->USpaceMapArray;
pNonphysical->RxBufDescQStart->USpaceMap = pMil->USpaceMapArray;
pNonphysical->RxBufDescQEnd->USpaceMap =
&(pMil->USpaceMapArray[pMil->RxRingSize - 1]);
for (i = 0; i < pMil->RxRingSize; i++) {
pNonphysical->RxBufDescQRead->descriptor->Rx_BCNT
= (unsigned)pMil->RxBufSize;
*(pNonphysical->RxBufDescQRead->USpaceMap) =
(long)(pLayerPointers->pOdl->rx_buf.next->vir_addr);
pNonphysical->RxBufDescQRead->descriptor->Rx_Base_Addr
= pLayerPointers->pOdl->rx_buf.next->phy_addr;
pNonphysical->RxBufDescQRead->descriptor->Rx_OWN = 1;
pNonphysical->RxBufDescQRead->descriptor++;
pNonphysical->RxBufDescQRead->USpaceMap++;
pLayerPointers->pOdl->rx_buf.next =
NEXT(pLayerPointers->pOdl->rx_buf, next);
}
pNonphysical->RxBufDescQRead->descriptor =
pNonphysical->RxBufDescQStart->descriptor;
pNonphysical->RxBufDescQRead->USpaceMap =
pNonphysical->RxBufDescQStart->USpaceMap;
pLayerPointers->pOdl->rx_buf.next =
pLayerPointers->pOdl->rx_buf.msg_buf;
}
void
milFreeResources(struct LayerPointers *pLayerPointers, ULONG *mem_free_array)
{
*(mem_free_array) = VIRTUAL;
*(++mem_free_array) = sizeof (struct mil);
*(++mem_free_array) = (ULONG)pLayerPointers->pMil;
*(++mem_free_array) = VIRTUAL;
*(++mem_free_array) = pLayerPointers->pMil->RxRingSize *
sizeof (unsigned long);
*(++mem_free_array) = (ULONG)pLayerPointers->pMil->USpaceMapArray;
*(++mem_free_array) = VIRTUAL;
*(++mem_free_array) = sizeof (struct nonphysical);
*(++mem_free_array) = (ULONG)pLayerPointers->pMil->pNonphysical;
*(++mem_free_array) = VIRTUAL;
*(++mem_free_array) = sizeof (struct Rx_Buf_Desc);
*(++mem_free_array) =
(ULONG)pLayerPointers->pMil->pNonphysical->RxBufDescQRead;
*(++mem_free_array) = VIRTUAL;
*(++mem_free_array) = sizeof (struct Rx_Buf_Desc);
*(++mem_free_array) =
(ULONG)pLayerPointers->pMil->pNonphysical->RxBufDescQStart;
*(++mem_free_array) = VIRTUAL;
*(++mem_free_array) = sizeof (struct Rx_Buf_Desc);
*(++mem_free_array) =
(ULONG)pLayerPointers->pMil->pNonphysical->RxBufDescQEnd;
*(++mem_free_array) = 0;
mdlFreeResources(pLayerPointers, mem_free_array);
}
void
milRequestResources(ULONG *mem_req_array)
{
int RxRingSize;
RxRingSize = RX_RING_SIZE;
*mem_req_array = VIRTUAL;
*(++mem_req_array) = sizeof (struct mil);
*(++mem_req_array) = VIRTUAL;
*(++mem_req_array) = RxRingSize * sizeof (unsigned long);
*(++mem_req_array) = VIRTUAL;
*(++mem_req_array) = sizeof (struct nonphysical);
*(++mem_req_array) = VIRTUAL;
*(++mem_req_array) = sizeof (struct Rx_Buf_Desc);
*(++mem_req_array) = VIRTUAL;
*(++mem_req_array) = sizeof (struct Rx_Buf_Desc);
*(++mem_req_array) = VIRTUAL;
*(++mem_req_array) = sizeof (struct Rx_Buf_Desc);
*(++mem_req_array) = 0;
mdlRequestResources(mem_req_array);
}
void
milSetResources(struct LayerPointers *pLayerPointers, ULONG *pmem_set_array)
{
int RxRingSize, TxRingSize;
int RxBufSize;
struct mil *pMil;
RxRingSize = RX_RING_SIZE;
TxRingSize = TX_RING_SIZE;
RxBufSize = RX_BUF_SIZE;
pmem_set_array++;
pmem_set_array++;
pMil = (struct mil *)(*pmem_set_array);
pLayerPointers->pMil = pMil;
pMil->RxRingSize = RxRingSize;
pMil->TxRingSize = TxRingSize;
pMil->RxBufSize = RxBufSize;
pmem_set_array++;
pmem_set_array++;
pmem_set_array++;
pMil->USpaceMapArray = (long *)(*pmem_set_array);
pmem_set_array++;
pmem_set_array++;
pmem_set_array++;
pMil->pNonphysical =
(struct nonphysical *)(*pmem_set_array);
pmem_set_array++;
pmem_set_array++;
pmem_set_array++;
pMil->pNonphysical->RxBufDescQRead =
(struct Rx_Buf_Desc *)(*pmem_set_array);
pmem_set_array++;
pmem_set_array++;
pmem_set_array++;
pMil->pNonphysical->RxBufDescQStart =
(struct Rx_Buf_Desc *)(*pmem_set_array);
pmem_set_array++;
pmem_set_array++;
pmem_set_array++;
pMil->pNonphysical->RxBufDescQEnd =
(struct Rx_Buf_Desc *)(*pmem_set_array);
pmem_set_array++;
mdlSetResources(pLayerPointers, pmem_set_array);
}
void
mdlAddMulticastAddress(struct LayerPointers *pLayerPointers,
UCHAR *pucMulticastAddress)
{
unsigned long MODE[10];
unsigned long tmp1;
unsigned long tmp2;
if (mdlMulticastBitMapping(pLayerPointers, pucMulticastAddress,
ADD_MULTICAST) != 0)
return;
tmp2 = SET_SINGLE_MULTICAST;
MODE[0] = (unsigned long)tmp2;
MODE[1] = 1;
tmp1 = (unsigned long)pucMulticastAddress;
MODE[2] = tmp1;
MODE[3] = ENABLE_MULTICAST;
MODE[4] = 0;
mdlChangeFilter(pLayerPointers, (unsigned long *)MODE);
}
void
mdlDeleteMulticastAddress(struct LayerPointers *pLayerPointers,
UCHAR *pucMulticastAddress)
{
unsigned long MODE[10];
unsigned long tmp;
if (mdlMulticastBitMapping(pLayerPointers, pucMulticastAddress,
DELETE_MULTICAST) != 0)
return;
MODE[0] = UNSET_SINGLE_MULTICAST;
MODE[1] = 1;
tmp = (unsigned long)pucMulticastAddress;
MODE[2] = tmp;
MODE[3] = ENABLE_MULTICAST;
MODE[4] = 0;
mdlChangeFilter(pLayerPointers, (unsigned long *)MODE);
}
static unsigned int
mdlCalculateCRC(unsigned int NumberOfBytes, unsigned char *Input)
{
const unsigned int POLY = 0x04c11db7;
unsigned int CRCValue = 0xffffffff;
unsigned int CurrentBit, CurrentCRCHigh;
unsigned char CurrentByte;
for (; NumberOfBytes; NumberOfBytes--) {
CurrentByte = *Input;
Input++;
for (CurrentBit = 8; CurrentBit; CurrentBit--) {
CurrentCRCHigh = CRCValue >> 31;
CRCValue <<= 1;
if (CurrentCRCHigh ^ (CurrentByte & 0x01)) {
CRCValue ^= POLY;
CRCValue |= 0x00000001;
}
CurrentByte >>= 1;
}
}
return (CRCValue);
}
void
mdlRxFastSuspend(struct LayerPointers *pLayerPointers)
{
WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address + CMD0,
VAL0 | RX_FAST_SPND);
}
void
mdlRxFastSuspendClear(struct LayerPointers *pLayerPointers)
{
WRITE_REG32(pLayerPointers, pLayerPointers->pMdl->Mem_Address + CMD0,
RX_FAST_SPND);
}