+void Rhine2_int_InitialiseCard(tCard *Card)
+{
+ tPAddr phys;
+
+ Card->MacAddr[0] = inb(Card->IOBase + REG_PAR0);
+ Card->MacAddr[1] = inb(Card->IOBase + REG_PAR1);
+ Card->MacAddr[2] = inb(Card->IOBase + REG_PAR2);
+ Card->MacAddr[3] = inb(Card->IOBase + REG_PAR3);
+ Card->MacAddr[4] = inb(Card->IOBase + REG_PAR4);
+ Card->MacAddr[5] = inb(Card->IOBase + REG_PAR5);
+
+ LOG("Resetting card");
+ outb(Card->IOBase + REG_CR1, CR1_SFRST);
+ // TODO: Timeout
+ while( inb(Card->IOBase + REG_CR1) & CR1_SFRST ) ;
+
+ LOG("Allocaating RX buffers");
+ // Allocate memory for things
+ for( int i = 0; i < N_RX_BUF_PAGES; i ++ )
+ {
+ Card->RXBuffers[i].Virt = (void*)MM_AllocDMA(1, 32, &phys);
+ Card->RXBuffers[i].Phys = phys;
+ }
+
+ LOG("Allocating and filling RX/TX Descriptors");
+ Card->DescTable = (void*)MM_AllocDMA(1, 32, &phys);
+ Card->DescTablePhys = phys;
+
+ // Initialise RX Descriptors
+ struct sRXDesc *rxdescs = Card->DescTable;
+ for( int i = 0; i < N_RX_DESCS; i ++ )
+ {
+ rxdescs[i].RSR = 0;
+ rxdescs[i].BufferSize = RX_BUF_SIZE;
+ rxdescs[i].RXBufferStart = Card->RXBuffers[i/N_RX_BUF_PER_PAGE].Phys
+ + (i % N_RX_BUF_PER_PAGE) * RX_BUF_SIZE;
+ rxdescs[i].RDBranchAddress = Card->DescTablePhys + (i+1) * DESC_SIZE;
+ rxdescs[i].Length = (1 << 15); // set OWN
+ LOG("RX Desc %p = {Buf:0x%8x, Next:0x%x}", rxdescs,
+ rxdescs[i].RXBufferStart, rxdescs[i].RDBranchAddress
+ );
+ }
+ rxdescs[ N_RX_DESCS - 1 ].RDBranchAddress = Card->DescTablePhys;
+ Card->NextRX = &rxdescs[0];
+
+ Card->TXDescs = (void*)(rxdescs + N_RX_DESCS);
+ memset(Card->TXDescs, 0, sizeof(struct sTXDesc)*N_TX_DESCS);
+ for( int i = 0; i < N_TX_DESCS; i ++ )
+ {
+ Card->TXDescs[i].TDBranchAddress = Card->DescTablePhys + (N_RX_DESCS + i + 1) * DESC_SIZE;
+ }
+ Card->TXDescs[N_TX_DESCS-1].TDBranchAddress = Card->DescTablePhys + N_RX_DESCS * DESC_SIZE;
+ Card->nFreeTX = N_TX_DESCS;
+ Card->NextTX = 0;
+
+ // - Initialise card state
+ LOG("Initialising card state");
+ outb(Card->IOBase + REG_IMR0, 0xFF);
+ outb(Card->IOBase + REG_IMR1, 0xFF);
+ outd(Card->IOBase + REG_CUR_RX_DESC, Card->DescTablePhys);
+ outd(Card->IOBase + REG_CUR_TX_DESC, Card->DescTablePhys + N_RX_DESCS * DESC_SIZE);
+
+ outb(Card->IOBase + REG_TCR, TCR_TRSF(4));
+
+ LOG("RX started");
+ outb(Card->IOBase + REG_CR0, CR0_BASEVAL);
+ outb(Card->IOBase + REG_CR1, 0); // Disabled TX polling only?
+
+ LOG("ISR state: %02x %02x", inb(Card->IOBase + REG_ISR0), inb(Card->IOBase + REG_ISR1));
+}
+