|
@@ -351,6 +351,11 @@ rtl8139reset(Ctlr* ctlr)
|
|
|
{
|
|
|
int timeo;
|
|
|
|
|
|
+ /* stop interrupts */
|
|
|
+ csr16w(ctlr, Imr, 0);
|
|
|
+ csr16w(ctlr, Isr, ~0);
|
|
|
+ csr32w(ctlr, TimerInt, 0);
|
|
|
+
|
|
|
/*
|
|
|
* Soft reset the controller.
|
|
|
*/
|
|
@@ -372,6 +377,7 @@ rtl8139halt(Ctlr* ctlr)
|
|
|
csr8w(ctlr, Cr, 0);
|
|
|
csr16w(ctlr, Imr, 0);
|
|
|
csr16w(ctlr, Isr, ~0);
|
|
|
+ csr32w(ctlr, TimerInt, 0);
|
|
|
|
|
|
for(i = 0; i < Ntd; i++){
|
|
|
if(ctlr->td[i].bp == nil)
|
|
@@ -437,13 +443,6 @@ rtl8139init(Ether* edev)
|
|
|
ctlr->ntd = ctlr->tdh = ctlr->tdi = 0;
|
|
|
ctlr->etxth = 128/32;
|
|
|
|
|
|
- /*
|
|
|
- * Interrupts.
|
|
|
- */
|
|
|
- csr32w(ctlr, TimerInt, 0);
|
|
|
- csr16w(ctlr, Imr, Serr|Timerbit|Fovw|PunLc|Rxovw|Ter|Tok|Rer|Rok);
|
|
|
- csr32w(ctlr, Mpc, 0);
|
|
|
-
|
|
|
/*
|
|
|
* Enable receiver/transmitter.
|
|
|
* Need to enable before writing the Rcr or it won't take.
|
|
@@ -455,6 +454,13 @@ rtl8139init(Ether* edev)
|
|
|
csr32w(ctlr, Mar0+4, 0);
|
|
|
ctlr->mchash = 0;
|
|
|
|
|
|
+ /*
|
|
|
+ * Interrupts.
|
|
|
+ */
|
|
|
+ csr32w(ctlr, TimerInt, 0);
|
|
|
+ csr16w(ctlr, Imr, Serr|Timerbit|Fovw|PunLc|Rxovw|Ter|Tok|Rer|Rok);
|
|
|
+ csr32w(ctlr, Mpc, 0);
|
|
|
+
|
|
|
iunlock(&ctlr->ilock);
|
|
|
}
|
|
|
|
|
@@ -463,11 +469,19 @@ rtl8139attach(Ether* edev)
|
|
|
{
|
|
|
Ctlr *ctlr;
|
|
|
|
|
|
+ if(edev == nil) {
|
|
|
+ print("rtl8139attach: nil edev\n");
|
|
|
+ return;
|
|
|
+ }
|
|
|
ctlr = edev->ctlr;
|
|
|
+ if(ctlr == nil) {
|
|
|
+ print("rtl8139attach: nil ctlr for Ether %#p\n", edev);
|
|
|
+ return;
|
|
|
+ }
|
|
|
qlock(&ctlr->alock);
|
|
|
if(ctlr->alloc == nil){
|
|
|
ctlr->rblen = 1<<((Rblen>>RblenSHIFT)+13);
|
|
|
- ctlr->alloc = mallocz(ctlr->rblen+16 + Ntd*Tdbsz + 32, 0);
|
|
|
+ ctlr->alloc = malloc(ctlr->rblen+16 + Ntd*Tdbsz + 32);
|
|
|
if(ctlr->alloc == nil) {
|
|
|
qunlock(&ctlr->alock);
|
|
|
error(Enomem);
|
|
@@ -537,6 +551,8 @@ rtl8139receive(Ether* edev)
|
|
|
* Capr is where the host is reading from,
|
|
|
* Cbr is where the NIC is currently writing.
|
|
|
*/
|
|
|
+ if(ctlr->rblen == 0)
|
|
|
+ return; /* not attached yet (shouldn't happen) */
|
|
|
capr = (csr16r(ctlr, Capr)+16) % ctlr->rblen;
|
|
|
while(!(csr8r(ctlr, Cr) & Bufe)){
|
|
|
p = ctlr->rbstart+capr;
|
|
@@ -616,9 +632,19 @@ rtl8139interrupt(Ureg*, void* arg)
|
|
|
|
|
|
edev = arg;
|
|
|
ctlr = edev->ctlr;
|
|
|
+ if(ctlr == nil) { /* not attached yet? (shouldn't happen) */
|
|
|
+ print("rtl8139interrupt: interrupt for unattached Ether %#p\n",
|
|
|
+ edev);
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
while((isr = csr16r(ctlr, Isr)) != 0){
|
|
|
csr16w(ctlr, Isr, isr);
|
|
|
+ if(ctlr->alloc == nil) {
|
|
|
+ print("rtl8139interrupt: interrupt for unattached Ctlr "
|
|
|
+ "%#p port %#p\n", ctlr, (void *)ctlr->port);
|
|
|
+ return; /* not attached yet (shouldn't happen) */
|
|
|
+ }
|
|
|
if(isr & (Fovw|PunLc|Rxovw|Rer|Rok)){
|
|
|
rtl8139receive(edev);
|
|
|
if(!(isr & Rok))
|
|
@@ -827,12 +853,12 @@ rtl8139pnp(Ether* edev)
|
|
|
edev->ea[5] = i>>8;
|
|
|
}
|
|
|
|
|
|
+ edev->arg = edev;
|
|
|
edev->attach = rtl8139attach;
|
|
|
edev->transmit = rtl8139transmit;
|
|
|
edev->interrupt = rtl8139interrupt;
|
|
|
edev->ifstat = rtl8139ifstat;
|
|
|
|
|
|
- edev->arg = edev;
|
|
|
edev->promiscuous = rtl8139promiscuous;
|
|
|
edev->multicast = rtl8139multicast;
|
|
|
edev->shutdown = rtl8139shutdown;
|