X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fnet%2Fwireless%2Fhermes.c;fp=drivers%2Fnet%2Fwireless%2Fhermes.c;h=346c6febb033b89e217591819727e21ae62ecc43;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hp=29d39105f5b869a4a59be436e41ab2015a3c822e;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c;p=linux-2.6.git diff --git a/drivers/net/wireless/hermes.c b/drivers/net/wireless/hermes.c index 29d39105f..346c6febb 100644 --- a/drivers/net/wireless/hermes.c +++ b/drivers/net/wireless/hermes.c @@ -38,6 +38,7 @@ * under either the MPL or the GPL. */ +#include #include #include #include @@ -120,6 +121,12 @@ void hermes_struct_init(hermes_t *hw, void __iomem *address, int reg_spacing) hw->iobase = address; hw->reg_spacing = reg_spacing; hw->inten = 0x0; + +#ifdef HERMES_DEBUG_BUFFER + hw->dbufp = 0; + memset(&hw->dbuf, 0xff, sizeof(hw->dbuf)); + memset(&hw->profile, 0, sizeof(hw->profile)); +#endif } int hermes_init(hermes_t *hw) @@ -340,6 +347,19 @@ static int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset) reg = hermes_read_reg(hw, oreg); } +#ifdef HERMES_DEBUG_BUFFER + hw->profile[HERMES_BAP_BUSY_TIMEOUT - k]++; + + if (k < HERMES_BAP_BUSY_TIMEOUT) { + struct hermes_debug_entry *e = + &hw->dbuf[(hw->dbufp++) % HERMES_DEBUG_BUFSIZE]; + e->bap = bap; + e->id = id; + e->offset = offset; + e->cycles = HERMES_BAP_BUSY_TIMEOUT - k; + } +#endif + if (reg & HERMES_OFFSET_BUSY) return -ETIMEDOUT; @@ -399,7 +419,8 @@ int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len, } /* Write a block of data to the chip's buffer, via the - * BAP. Synchronization/serialization is the caller's problem. + * BAP. Synchronization/serialization is the caller's problem. len + * must be even. * * Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware */ @@ -409,7 +430,7 @@ int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len, int dreg = bap ? HERMES_DATA1 : HERMES_DATA0; int err = 0; - if (len < 0) + if ( (len < 0) || (len % 2) ) return -EINVAL; err = hermes_bap_seek(hw, bap, id, offset); @@ -417,12 +438,49 @@ int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len, goto out; /* Actually do the transfer */ - hermes_write_bytes(hw, dreg, buf, len); + hermes_write_words(hw, dreg, buf, len/2); out: return err; } +/* Write a block of data to the chip's buffer with padding if + * neccessary, via the BAP. Synchronization/serialization is the + * caller's problem. len must be even. + * + * Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware + */ +int hermes_bap_pwrite_pad(hermes_t *hw, int bap, const void *buf, unsigned data_len, int len, + u16 id, u16 offset) +{ + int dreg = bap ? HERMES_DATA1 : HERMES_DATA0; + int err = 0; + + if (len < 0 || len % 2 || data_len > len) + return -EINVAL; + + err = hermes_bap_seek(hw, bap, id, offset); + if (err) + goto out; + + /* Transfer all the complete words of data */ + hermes_write_words(hw, dreg, buf, data_len/2); + /* If there is an odd byte left over pad and transfer it */ + if (data_len & 1) { + u8 end[2]; + end[1] = 0; + end[0] = ((unsigned char *)buf)[data_len - 1]; + hermes_write_words(hw, dreg, end, 1); + data_len ++; + } + /* Now send zeros for the padding */ + if (data_len < len) + hermes_clear_words(hw, dreg, (len - data_len) / 2); + /* Complete */ + out: + return err; +} + /* Read a Length-Type-Value record from the card. * * If length is NULL, we ignore the length read from the card, and @@ -495,7 +553,7 @@ int hermes_write_ltv(hermes_t *hw, int bap, u16 rid, count = length - 1; - hermes_write_bytes(hw, dreg, value, count << 1); + hermes_write_words(hw, dreg, value, count); err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS | HERMES_CMD_WRITE, rid, NULL); @@ -510,6 +568,7 @@ EXPORT_SYMBOL(hermes_allocate); EXPORT_SYMBOL(hermes_bap_pread); EXPORT_SYMBOL(hermes_bap_pwrite); +EXPORT_SYMBOL(hermes_bap_pwrite_pad); EXPORT_SYMBOL(hermes_read_ltv); EXPORT_SYMBOL(hermes_write_ltv);