This is the mail archive of the
ecos-discuss@sourceware.org
mailing list for the eCos project.
Ever learning, setting individual bits
- From: Chuck McManis <ecos at mcmanis dot com>
- To: ECOS Discussion Group <ecos-discuss at sources dot redhat dot com>
- Date: Sat, 18 Feb 2006 16:33:04 -0800
- Subject: [ECOS] Ever learning, setting individual bits
So my driver still isn't working. But there are two clues that I have and
I'm working from that angle.
First, a person who has gotten VIA ethernet drivers to work in the past
warned me about programming bits that VIA's data sheets said not to
program. In particular he encouraged me to read the old value, just change
the bits I want, and write the new value. In looking at the if_vr.c code in
FreeBSD I see that the author of that code has done something similar. I
coded up a few macros to do that on 8 and 16 bit registers (they are
included below). They could be useful in the HAL layer if there isn't
something like them already there.
Second, on closer inspection I've ascertained that my driver is never
actually getting packets out on the wire. This makes me suspect that there
is some setup between the PHY and the switch that haven't correctly
negotiated their setup. Again in the if_vr.c code there is extensive
MAC/PHY setup but in the old Rhine driver there was very little (the D-link
card is pretty simple I guess).
I'd love to be compliant with the emerging drv_eth_phy architecture but
there doesn't seem to be a parameter in the calls to phy_reg_read and
phy_reg_write that would allow me to identify the base address of the MAC
(which is the only way to talk to the phy, by telling the mac to send it
messages). If I squirrel away a local copy then my driver won't work if
there are multiple MAC/PHY pairs present. What to do?
--Chuck
------------BIT set/clear macros for I/O registers
/*
* A bit of syntactic sugar around setting and resetting bits in
* 8 and 16 bit IO registers. A number of registers have reserved
* bits that are marked "do not program" which means don't ever
* change them if you expect your driver to work. So these macros
* automate the process of reading the old value, oring in or anding
* out the bits that are set in the pattern 'bits' and then writing
* the result back to the register.
*/
#define IO_BIT_SET_8(base, offset, bits) \
CYG_MACRO_START \
cyg_uint8 datum; \
HAL_PCI_IO_READ_UINT8((base) + (offset), datum); \
datum |= (cyg_uint8)(bits); \
HAL_PCI_IO_wRITE_UINT8((base) + (offset), datum); \
CYG_MACRO_END
#define IO_BIT_CLR_8(base, offset, bits) \
CYG_MACRO_START \
cyg_uint8 datum; \
HAL_PCI_IO_READ_UINT8((base) + (offset), datum); \
datum &= ~((cyg_uint8)(bits)); \
HAL_PCI_IO_wRITE_UINT8((base) + (offset), datum); \
CYG_MACRO_END
#define IO_BIT_SET_16(base, offset, bits) \
CYG_MACRO_START \
cyg_uint16 datum; \
HAL_PCI_IO_READ_UINT16((base) + (offset), datum); \
datum |= (cyg_uint16)(bits); \
HAL_PCI_IO_wRITE_UINT16((base) + (offset), datum); \
CYG_MACRO_END
#define IO_BIT_CLR_16(base, offset, bits) \
CYG_MACRO_START \
cyg_uint16 datum; \
HAL_PCI_IO_READ_UINT16((base) + (offset), datum); \
datum &= ~((cyg_uint16)(bits)); \
HAL_PCI_IO_wRITE_UINT16((base) + (offset), datum); \
CYG_MACRO_END
--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss