Page 1 of 1

problem reading from nic's eeprom

Posted: Sat Mar 02, 2013 2:25 am
by dansmahajan
hey everyone i've started working on intel's 82540em nic driver, i can detect the card but im unable to read the data from its eeprom. I've tried using both the mmio and io but none of them worked.

Code: Select all

after decoding: bar address-F0000000 for mmio
and bar address-D101 for io
so where am i lagging ??

Re: problem reading from nic's eeprom

Posted: Sat Mar 02, 2013 5:59 am
by Combuster
You didn't write the code for the actual read yet? :wink:

Re: problem reading from nic's eeprom

Posted: Sun Mar 03, 2013 12:02 pm
by dansmahajan
following is my read code:

Code: Select all

//iterating over all the buses(256) and all the slots(32)
pci_device_t *dev = get_pci_device(bus,device,0);
pci_device _bar_t bar = get_pci_bar(dev,0);
pci_device _bar_t bar2 = get_pci_bar(dev,0);

u32int *mmio = (u32int *)bar2->address;
u32int *ctrl = mmio;
u32int *ioaddr = (u32int *)bar2->address;
u32int *iodata = ioaddr + 0x4;
				
puts("\n resetting pci bt ctrl_ext");
outportl(ioaddr,0x18);
outportl(iodata,inportl(iodata)|1<<13);				

outportl(ioaddr,0x00);
outportl(iodata,1<<6);//Set link up
outportl(ioaddr,0x8);
int x=inportl(iodata);
//checking is link up 
if(x & 2){
puts("\nLINK UP");puthex(x);}
else puts("\nLINK DOWN ");
above is code when im accessing the eeprom via io mapping

Code: Select all

u32int *mmio=bar->address;
u32int *ctrl = mmio;
u32int *status = mmio +0x8;
*ctrl = *ctrl | 1<<6;//Setting link up
u32int val = *status;
if(x&2)//checking is link up
puts("link up");
else puts("link down");
the above code is setting the link up and checking it via mmio

Code: Select all


u32int pciConfigRead (u16int bus, u16int device_no,
                                   u16int func, u16int reg_no)
 {
    u32int address;
    u32int tmp = 0;
    address = (unsigned int)((bus << 16) | (device_no << 11) |
              (func << 8) | (reg_no & 0xfc) | ((u32int)0x80000000));

    outportl (0xCF8, address);
    
    tmp = (u32int)inportl (0xCFC);
    return (tmp);
 }

pci_device_t* get_pci_device(u16int bus,u16int device,u16int func)
{	
	pci_device_t *dev = (pci_device_t *)phys_kmalloc(sizeof(pci_device_t));
	dev->bus = bus;
	dev->slot = device;
	dev->function = func;
	dev->deviceID = get_deviceID(bus,device,func);
	dev->vendorID = get_vendorID(bus,device,func);
	dev->class_code = get_class_code(bus,device,func);
	dev->subclass = get_sub_class(bus,device,func);
	dev->progIF = get_progIF(bus,device,func);
	dev->header = get_header_type(bus,device,func);
	return dev;
}

pci_device_bar_t *get_pci_bar(pci_device_t *dev,u32int bar_no)
{
	pci_device_bar_t *bar = (pci_device_bar_t*)phys_kmalloc(sizeof(pci_device_bar_t));
	u32int tmp = pciConfigRead(dev->bus,dev->slot,dev->function,0x10+(bar_no*4));
	bar->is_MMIO = (tmp&0x1)?0:1;
	if(bar->is_MMIO)
	{
		bar->prefetchable = tmp&0x8;
		bar->type = tmp&0x6;
		if(bar->type == PCI_BAR_32MEM)//32mb wide mem space
		{
			bar->address = tmp&0xFFFFFFF0;
		}
		if(bar->type == PCI_BAR_64MEM)//64mb wide mem space
		{
			//u32int a1 = t
		}
		if(bar->type == PCI_BAR_16MEM)//16mb wide mem space
		{
			bar->address = tmp&0xFFF0;
		}
	}
	else
	{
		bar->type=-1;
		bar->prefetchable=-1;
		bar->address = tmp & 0xFFFFFFFC;
	}
	return bar;
	//return;
}
so what am i doing wrong?

Re: problem reading from nic's eeprom

Posted: Sun Mar 03, 2013 3:49 pm
by Combuster
pci_device _bar_t bar = get_pci_bar(dev,0);
pci_device _bar_t bar2 = get_pci_bar(dev,0);
I doubt mmio maps to identical addresses as port io does...

Re: problem reading from nic's eeprom

Posted: Mon Mar 04, 2013 4:24 am
by dansmahajan
sorry that is

Code: Select all

bar2 = get_pci_bar(dev,2);

Re: problem reading from nic's eeprom

Posted: Mon Mar 04, 2013 5:40 am
by Combuster
Assuming you fixed and tested that (or worse, shame on you for not properly copy-pasting), a next look revealed the following suspicious bit:

Code: Select all

u32int *iodata = ioaddr + 0x4; // adding 4 * sizeof(u32int) 
Is that register actually at offset 16 (pointer math failure)?