* [net-next-2.6 9/9] ixgbe: Cleanup PCIe bus speed info
From: Jeff Kirsher @ 2011-05-04 19:30 UTC (permalink / raw)
To: davem; +Cc: Don Skidmore, netdev, gospo, bphilips, Jeff Kirsher
In-Reply-To: <1304537441-2056-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Don Skidmore <donald.c.skidmore@intel.com>
PCIe connections should be expressed as GT/s (GigaTransfers per second)
instead of the current Gb/s (Gigabits per second). In addition, it is
incorrect because (due to PCIe gen 1 & 2 having a 20% overhead) the
actually data rate, when expressed in Gb/s, is only 80% of the rate of
GT/s.
Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com>
Tested-by: Evan Swanson <evan.swanson@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ixgbe/ixgbe_main.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index bd3d21d..eebb192 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -7469,8 +7469,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
/* print bus type/speed/width info */
e_dev_info("(PCI Express:%s:%s) %pM\n",
- (hw->bus.speed == ixgbe_bus_speed_5000 ? "5.0Gb/s" :
- hw->bus.speed == ixgbe_bus_speed_2500 ? "2.5Gb/s" :
+ (hw->bus.speed == ixgbe_bus_speed_5000 ? "5.0GT/s" :
+ hw->bus.speed == ixgbe_bus_speed_2500 ? "2.5GT/s" :
"Unknown"),
(hw->bus.width == ixgbe_bus_width_pcie_x8 ? "Width x8" :
hw->bus.width == ixgbe_bus_width_pcie_x4 ? "Width x4" :
--
1.7.4.4
^ permalink raw reply related
* [net-next-2.6 8/9] ixgbe: improve EEPROM read/write operations
From: Jeff Kirsher @ 2011-05-04 19:30 UTC (permalink / raw)
To: davem; +Cc: Emil Tantilov, netdev, gospo, bphilips, Jeff Kirsher
In-Reply-To: <1304537441-2056-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Emil Tantilov <emil.s.tantilov@intel.com>
Introduce buffered read/writes which greatly improves performance on
parts with large EEPROMs.
Previously reading/writing a word requires taking/releasing of synchronization
semaphores which adds 10ms to each operation. The optimization is to
read/write in buffers, but make sure the semaphore is not held for >500ms
according to the datasheet.
Since we can't read the EEPROM page size ixgbe_detect_eeprom_page_size() is
used to discover the EEPROM size when needed and keeps the result in
word_page_size for the rest of the run time.
Use buffered reads for ethtool -e.
Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
Tested-by: Evan Swanson <evan.swanson@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ixgbe/ixgbe_82598.c | 1 +
drivers/net/ixgbe/ixgbe_82599.c | 35 +++
drivers/net/ixgbe/ixgbe_common.c | 440 +++++++++++++++++++++++++++++--------
drivers/net/ixgbe/ixgbe_common.h | 8 +
drivers/net/ixgbe/ixgbe_ethtool.c | 7 +-
drivers/net/ixgbe/ixgbe_type.h | 7 +
drivers/net/ixgbe/ixgbe_x540.c | 67 +++++-
7 files changed, 465 insertions(+), 100 deletions(-)
diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c
index 7a64f50..8179e50 100644
--- a/drivers/net/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ixgbe/ixgbe_82598.c
@@ -1281,6 +1281,7 @@ static struct ixgbe_mac_operations mac_ops_82598 = {
static struct ixgbe_eeprom_operations eeprom_ops_82598 = {
.init_params = &ixgbe_init_eeprom_params_generic,
.read = &ixgbe_read_eerd_generic,
+ .read_buffer = &ixgbe_read_eerd_buffer_generic,
.calc_checksum = &ixgbe_calc_eeprom_checksum_generic,
.validate_checksum = &ixgbe_validate_eeprom_checksum_generic,
.update_checksum = &ixgbe_update_eeprom_checksum_generic,
diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c
index 5b8e17e..dba5ca6 100644
--- a/drivers/net/ixgbe/ixgbe_82599.c
+++ b/drivers/net/ixgbe/ixgbe_82599.c
@@ -2064,6 +2064,39 @@ out:
}
/**
+ * ixgbe_read_eeprom_buffer_82599 - Read EEPROM word(s) using
+ * fastest available method
+ *
+ * @hw: pointer to hardware structure
+ * @offset: offset of word in EEPROM to read
+ * @words: number of words
+ * @data: word(s) read from the EEPROM
+ *
+ * Retrieves 16 bit word(s) read from EEPROM
+ **/
+static s32 ixgbe_read_eeprom_buffer_82599(struct ixgbe_hw *hw, u16 offset,
+ u16 words, u16 *data)
+{
+ struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
+ s32 ret_val = IXGBE_ERR_CONFIG;
+
+ /*
+ * If EEPROM is detected and can be addressed using 14 bits,
+ * use EERD otherwise use bit bang
+ */
+ if ((eeprom->type == ixgbe_eeprom_spi) &&
+ (offset + (words - 1) <= IXGBE_EERD_MAX_ADDR))
+ ret_val = ixgbe_read_eerd_buffer_generic(hw, offset, words,
+ data);
+ else
+ ret_val = ixgbe_read_eeprom_buffer_bit_bang_generic(hw, offset,
+ words,
+ data);
+
+ return ret_val;
+}
+
+/**
* ixgbe_read_eeprom_82599 - Read EEPROM word using
* fastest available method
*
@@ -2139,7 +2172,9 @@ static struct ixgbe_mac_operations mac_ops_82599 = {
static struct ixgbe_eeprom_operations eeprom_ops_82599 = {
.init_params = &ixgbe_init_eeprom_params_generic,
.read = &ixgbe_read_eeprom_82599,
+ .read_buffer = &ixgbe_read_eeprom_buffer_82599,
.write = &ixgbe_write_eeprom_generic,
+ .write_buffer = &ixgbe_write_eeprom_buffer_bit_bang_generic,
.calc_checksum = &ixgbe_calc_eeprom_checksum_generic,
.validate_checksum = &ixgbe_validate_eeprom_checksum_generic,
.update_checksum = &ixgbe_update_eeprom_checksum_generic,
diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c
index cb2e8e1..c4730cd 100644
--- a/drivers/net/ixgbe/ixgbe_common.c
+++ b/drivers/net/ixgbe/ixgbe_common.c
@@ -55,6 +55,12 @@ static s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg,
u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm);
static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num);
static s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg);
+static s32 ixgbe_read_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
+ u16 words, u16 *data);
+static s32 ixgbe_write_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
+ u16 words, u16 *data);
+static s32 ixgbe_detect_eeprom_page_size_generic(struct ixgbe_hw *hw,
+ u16 offset);
/**
* ixgbe_start_hw_generic - Prepare hardware for Tx/Rx
@@ -585,6 +591,8 @@ s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw)
/* Set default semaphore delay to 10ms which is a well
* tested value */
eeprom->semaphore_delay = 10;
+ /* Clear EEPROM page size, it will be initialized as needed */
+ eeprom->word_page_size = 0;
/*
* Check for EEPROM present first.
@@ -617,26 +625,78 @@ s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw)
}
/**
- * ixgbe_write_eeprom_generic - Writes 16 bit value to EEPROM
+ * ixgbe_write_eeprom_buffer_bit_bang_generic - Write EEPROM using bit-bang
* @hw: pointer to hardware structure
- * @offset: offset within the EEPROM to be written to
- * @data: 16 bit word to be written to the EEPROM
+ * @offset: offset within the EEPROM to write
+ * @words: number of words
+ * @data: 16 bit word(s) to write to EEPROM
*
- * If ixgbe_eeprom_update_checksum is not called after this function, the
- * EEPROM will most likely contain an invalid checksum.
+ * Reads 16 bit word(s) from EEPROM through bit-bang method
**/
-s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data)
+s32 ixgbe_write_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
+ u16 words, u16 *data)
{
- s32 status;
- u8 write_opcode = IXGBE_EEPROM_WRITE_OPCODE_SPI;
+ s32 status = 0;
+ u16 i, count;
hw->eeprom.ops.init_params(hw);
- if (offset >= hw->eeprom.word_size) {
+ if (words == 0) {
+ status = IXGBE_ERR_INVALID_ARGUMENT;
+ goto out;
+ }
+
+ if (offset + words > hw->eeprom.word_size) {
status = IXGBE_ERR_EEPROM;
goto out;
}
+ /*
+ * The EEPROM page size cannot be queried from the chip. We do lazy
+ * initialization. It is worth to do that when we write large buffer.
+ */
+ if ((hw->eeprom.word_page_size == 0) &&
+ (words > IXGBE_EEPROM_PAGE_SIZE_MAX))
+ ixgbe_detect_eeprom_page_size_generic(hw, offset);
+
+ /*
+ * We cannot hold synchronization semaphores for too long
+ * to avoid other entity starvation. However it is more efficient
+ * to read in bursts than synchronizing access for each word.
+ */
+ for (i = 0; i < words; i += IXGBE_EEPROM_RD_BUFFER_MAX_COUNT) {
+ count = (words - i) / IXGBE_EEPROM_RD_BUFFER_MAX_COUNT > 0 ?
+ IXGBE_EEPROM_RD_BUFFER_MAX_COUNT : (words - i);
+ status = ixgbe_write_eeprom_buffer_bit_bang(hw, offset + i,
+ count, &data[i]);
+
+ if (status != 0)
+ break;
+ }
+
+out:
+ return status;
+}
+
+/**
+ * ixgbe_write_eeprom_buffer_bit_bang - Writes 16 bit word(s) to EEPROM
+ * @hw: pointer to hardware structure
+ * @offset: offset within the EEPROM to be written to
+ * @words: number of word(s)
+ * @data: 16 bit word(s) to be written to the EEPROM
+ *
+ * If ixgbe_eeprom_update_checksum is not called after this function, the
+ * EEPROM will most likely contain an invalid checksum.
+ **/
+static s32 ixgbe_write_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
+ u16 words, u16 *data)
+{
+ s32 status;
+ u16 word;
+ u16 page_size;
+ u16 i;
+ u8 write_opcode = IXGBE_EEPROM_WRITE_OPCODE_SPI;
+
/* Prepare the EEPROM for writing */
status = ixgbe_acquire_eeprom(hw);
@@ -648,62 +708,147 @@ s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data)
}
if (status == 0) {
- ixgbe_standby_eeprom(hw);
+ for (i = 0; i < words; i++) {
+ ixgbe_standby_eeprom(hw);
- /* Send the WRITE ENABLE command (8 bit opcode ) */
- ixgbe_shift_out_eeprom_bits(hw, IXGBE_EEPROM_WREN_OPCODE_SPI,
- IXGBE_EEPROM_OPCODE_BITS);
+ /* Send the WRITE ENABLE command (8 bit opcode ) */
+ ixgbe_shift_out_eeprom_bits(hw,
+ IXGBE_EEPROM_WREN_OPCODE_SPI,
+ IXGBE_EEPROM_OPCODE_BITS);
- ixgbe_standby_eeprom(hw);
+ ixgbe_standby_eeprom(hw);
- /*
- * Some SPI eeproms use the 8th address bit embedded in the
- * opcode
- */
- if ((hw->eeprom.address_bits == 8) && (offset >= 128))
- write_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
+ /*
+ * Some SPI eeproms use the 8th address bit embedded
+ * in the opcode
+ */
+ if ((hw->eeprom.address_bits == 8) &&
+ ((offset + i) >= 128))
+ write_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
+
+ /* Send the Write command (8-bit opcode + addr) */
+ ixgbe_shift_out_eeprom_bits(hw, write_opcode,
+ IXGBE_EEPROM_OPCODE_BITS);
+ ixgbe_shift_out_eeprom_bits(hw, (u16)((offset + i) * 2),
+ hw->eeprom.address_bits);
+
+ page_size = hw->eeprom.word_page_size;
+
+ /* Send the data in burst via SPI*/
+ do {
+ word = data[i];
+ word = (word >> 8) | (word << 8);
+ ixgbe_shift_out_eeprom_bits(hw, word, 16);
+
+ if (page_size == 0)
+ break;
+
+ /* do not wrap around page */
+ if (((offset + i) & (page_size - 1)) ==
+ (page_size - 1))
+ break;
+ } while (++i < words);
+
+ ixgbe_standby_eeprom(hw);
+ usleep_range(10000, 20000);
+ }
+ /* Done with writing - release the EEPROM */
+ ixgbe_release_eeprom(hw);
+ }
- /* Send the Write command (8-bit opcode + addr) */
- ixgbe_shift_out_eeprom_bits(hw, write_opcode,
- IXGBE_EEPROM_OPCODE_BITS);
- ixgbe_shift_out_eeprom_bits(hw, (u16)(offset*2),
- hw->eeprom.address_bits);
+ return status;
+}
- /* Send the data */
- data = (data >> 8) | (data << 8);
- ixgbe_shift_out_eeprom_bits(hw, data, 16);
- ixgbe_standby_eeprom(hw);
+/**
+ * ixgbe_write_eeprom_generic - Writes 16 bit value to EEPROM
+ * @hw: pointer to hardware structure
+ * @offset: offset within the EEPROM to be written to
+ * @data: 16 bit word to be written to the EEPROM
+ *
+ * If ixgbe_eeprom_update_checksum is not called after this function, the
+ * EEPROM will most likely contain an invalid checksum.
+ **/
+s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data)
+{
+ s32 status;
- /* Done with writing - release the EEPROM */
- ixgbe_release_eeprom(hw);
+ hw->eeprom.ops.init_params(hw);
+
+ if (offset >= hw->eeprom.word_size) {
+ status = IXGBE_ERR_EEPROM;
+ goto out;
}
+ status = ixgbe_write_eeprom_buffer_bit_bang(hw, offset, 1, &data);
+
out:
return status;
}
/**
- * ixgbe_read_eeprom_bit_bang_generic - Read EEPROM word using bit-bang
+ * ixgbe_read_eeprom_buffer_bit_bang_generic - Read EEPROM using bit-bang
* @hw: pointer to hardware structure
* @offset: offset within the EEPROM to be read
- * @data: read 16 bit value from EEPROM
+ * @words: number of word(s)
+ * @data: read 16 bit words(s) from EEPROM
*
- * Reads 16 bit value from EEPROM through bit-bang method
+ * Reads 16 bit word(s) from EEPROM through bit-bang method
**/
-s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
- u16 *data)
+s32 ixgbe_read_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
+ u16 words, u16 *data)
{
- s32 status;
- u16 word_in;
- u8 read_opcode = IXGBE_EEPROM_READ_OPCODE_SPI;
+ s32 status = 0;
+ u16 i, count;
hw->eeprom.ops.init_params(hw);
- if (offset >= hw->eeprom.word_size) {
+ if (words == 0) {
+ status = IXGBE_ERR_INVALID_ARGUMENT;
+ goto out;
+ }
+
+ if (offset + words > hw->eeprom.word_size) {
status = IXGBE_ERR_EEPROM;
goto out;
}
+ /*
+ * We cannot hold synchronization semaphores for too long
+ * to avoid other entity starvation. However it is more efficient
+ * to read in bursts than synchronizing access for each word.
+ */
+ for (i = 0; i < words; i += IXGBE_EEPROM_RD_BUFFER_MAX_COUNT) {
+ count = (words - i) / IXGBE_EEPROM_RD_BUFFER_MAX_COUNT > 0 ?
+ IXGBE_EEPROM_RD_BUFFER_MAX_COUNT : (words - i);
+
+ status = ixgbe_read_eeprom_buffer_bit_bang(hw, offset + i,
+ count, &data[i]);
+
+ if (status != 0)
+ break;
+ }
+
+out:
+ return status;
+}
+
+/**
+ * ixgbe_read_eeprom_buffer_bit_bang - Read EEPROM using bit-bang
+ * @hw: pointer to hardware structure
+ * @offset: offset within the EEPROM to be read
+ * @words: number of word(s)
+ * @data: read 16 bit word(s) from EEPROM
+ *
+ * Reads 16 bit word(s) from EEPROM through bit-bang method
+ **/
+static s32 ixgbe_read_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
+ u16 words, u16 *data)
+{
+ s32 status;
+ u16 word_in;
+ u8 read_opcode = IXGBE_EEPROM_READ_OPCODE_SPI;
+ u16 i;
+
/* Prepare the EEPROM for reading */
status = ixgbe_acquire_eeprom(hw);
@@ -715,104 +860,208 @@ s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
}
if (status == 0) {
- ixgbe_standby_eeprom(hw);
+ for (i = 0; i < words; i++) {
+ ixgbe_standby_eeprom(hw);
+ /*
+ * Some SPI eeproms use the 8th address bit embedded
+ * in the opcode
+ */
+ if ((hw->eeprom.address_bits == 8) &&
+ ((offset + i) >= 128))
+ read_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
+
+ /* Send the READ command (opcode + addr) */
+ ixgbe_shift_out_eeprom_bits(hw, read_opcode,
+ IXGBE_EEPROM_OPCODE_BITS);
+ ixgbe_shift_out_eeprom_bits(hw, (u16)((offset + i) * 2),
+ hw->eeprom.address_bits);
+
+ /* Read the data. */
+ word_in = ixgbe_shift_in_eeprom_bits(hw, 16);
+ data[i] = (word_in >> 8) | (word_in << 8);
+ }
- /*
- * Some SPI eeproms use the 8th address bit embedded in the
- * opcode
- */
- if ((hw->eeprom.address_bits == 8) && (offset >= 128))
- read_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
+ /* End this read operation */
+ ixgbe_release_eeprom(hw);
+ }
- /* Send the READ command (opcode + addr) */
- ixgbe_shift_out_eeprom_bits(hw, read_opcode,
- IXGBE_EEPROM_OPCODE_BITS);
- ixgbe_shift_out_eeprom_bits(hw, (u16)(offset*2),
- hw->eeprom.address_bits);
+ return status;
+}
- /* Read the data. */
- word_in = ixgbe_shift_in_eeprom_bits(hw, 16);
- *data = (word_in >> 8) | (word_in << 8);
+/**
+ * ixgbe_read_eeprom_bit_bang_generic - Read EEPROM word using bit-bang
+ * @hw: pointer to hardware structure
+ * @offset: offset within the EEPROM to be read
+ * @data: read 16 bit value from EEPROM
+ *
+ * Reads 16 bit value from EEPROM through bit-bang method
+ **/
+s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
+ u16 *data)
+{
+ s32 status;
- /* End this read operation */
- ixgbe_release_eeprom(hw);
+ hw->eeprom.ops.init_params(hw);
+
+ if (offset >= hw->eeprom.word_size) {
+ status = IXGBE_ERR_EEPROM;
+ goto out;
}
+ status = ixgbe_read_eeprom_buffer_bit_bang(hw, offset, 1, data);
+
out:
return status;
}
/**
- * ixgbe_read_eerd_generic - Read EEPROM word using EERD
+ * ixgbe_read_eerd_buffer_generic - Read EEPROM word(s) using EERD
* @hw: pointer to hardware structure
- * @offset: offset of word in the EEPROM to read
- * @data: word read from the EEPROM
+ * @offset: offset of word in the EEPROM to read
+ * @words: number of word(s)
+ * @data: 16 bit word(s) from the EEPROM
*
- * Reads a 16 bit word from the EEPROM using the EERD register.
+ * Reads a 16 bit word(s) from the EEPROM using the EERD register.
**/
-s32 ixgbe_read_eerd_generic(struct ixgbe_hw *hw, u16 offset, u16 *data)
+s32 ixgbe_read_eerd_buffer_generic(struct ixgbe_hw *hw, u16 offset,
+ u16 words, u16 *data)
{
u32 eerd;
- s32 status;
+ s32 status = 0;
+ u32 i;
hw->eeprom.ops.init_params(hw);
+ if (words == 0) {
+ status = IXGBE_ERR_INVALID_ARGUMENT;
+ goto out;
+ }
+
if (offset >= hw->eeprom.word_size) {
status = IXGBE_ERR_EEPROM;
goto out;
}
- eerd = (offset << IXGBE_EEPROM_RW_ADDR_SHIFT) +
- IXGBE_EEPROM_RW_REG_START;
+ for (i = 0; i < words; i++) {
+ eerd = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) +
+ IXGBE_EEPROM_RW_REG_START;
- IXGBE_WRITE_REG(hw, IXGBE_EERD, eerd);
- status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_READ);
+ IXGBE_WRITE_REG(hw, IXGBE_EERD, eerd);
+ status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_READ);
- if (status == 0)
- *data = (IXGBE_READ_REG(hw, IXGBE_EERD) >>
- IXGBE_EEPROM_RW_REG_DATA);
- else
- hw_dbg(hw, "Eeprom read timed out\n");
+ if (status == 0) {
+ data[i] = (IXGBE_READ_REG(hw, IXGBE_EERD) >>
+ IXGBE_EEPROM_RW_REG_DATA);
+ } else {
+ hw_dbg(hw, "Eeprom read timed out\n");
+ goto out;
+ }
+ }
+out:
+ return status;
+}
+/**
+ * ixgbe_detect_eeprom_page_size_generic - Detect EEPROM page size
+ * @hw: pointer to hardware structure
+ * @offset: offset within the EEPROM to be used as a scratch pad
+ *
+ * Discover EEPROM page size by writing marching data at given offset.
+ * This function is called only when we are writing a new large buffer
+ * at given offset so the data would be overwritten anyway.
+ **/
+static s32 ixgbe_detect_eeprom_page_size_generic(struct ixgbe_hw *hw,
+ u16 offset)
+{
+ u16 data[IXGBE_EEPROM_PAGE_SIZE_MAX];
+ s32 status = 0;
+ u16 i;
+
+ for (i = 0; i < IXGBE_EEPROM_PAGE_SIZE_MAX; i++)
+ data[i] = i;
+
+ hw->eeprom.word_page_size = IXGBE_EEPROM_PAGE_SIZE_MAX;
+ status = ixgbe_write_eeprom_buffer_bit_bang(hw, offset,
+ IXGBE_EEPROM_PAGE_SIZE_MAX, data);
+ hw->eeprom.word_page_size = 0;
+ if (status != 0)
+ goto out;
+
+ status = ixgbe_read_eeprom_buffer_bit_bang(hw, offset, 1, data);
+ if (status != 0)
+ goto out;
+
+ /*
+ * When writing in burst more than the actual page size
+ * EEPROM address wraps around current page.
+ */
+ hw->eeprom.word_page_size = IXGBE_EEPROM_PAGE_SIZE_MAX - data[0];
+
+ hw_dbg(hw, "Detected EEPROM page size = %d words.",
+ hw->eeprom.word_page_size);
out:
return status;
}
/**
- * ixgbe_write_eewr_generic - Write EEPROM word using EEWR
+ * ixgbe_read_eerd_generic - Read EEPROM word using EERD
+ * @hw: pointer to hardware structure
+ * @offset: offset of word in the EEPROM to read
+ * @data: word read from the EEPROM
+ *
+ * Reads a 16 bit word from the EEPROM using the EERD register.
+ **/
+s32 ixgbe_read_eerd_generic(struct ixgbe_hw *hw, u16 offset, u16 *data)
+{
+ return ixgbe_read_eerd_buffer_generic(hw, offset, 1, data);
+}
+
+/**
+ * ixgbe_write_eewr_buffer_generic - Write EEPROM word(s) using EEWR
* @hw: pointer to hardware structure
* @offset: offset of word in the EEPROM to write
- * @data: word write to the EEPROM
+ * @words: number of words
+ * @data: word(s) write to the EEPROM
*
- * Write a 16 bit word to the EEPROM using the EEWR register.
+ * Write a 16 bit word(s) to the EEPROM using the EEWR register.
**/
-s32 ixgbe_write_eewr_generic(struct ixgbe_hw *hw, u16 offset, u16 data)
+s32 ixgbe_write_eewr_buffer_generic(struct ixgbe_hw *hw, u16 offset,
+ u16 words, u16 *data)
{
u32 eewr;
- s32 status;
+ s32 status = 0;
+ u16 i;
hw->eeprom.ops.init_params(hw);
+ if (words == 0) {
+ status = IXGBE_ERR_INVALID_ARGUMENT;
+ goto out;
+ }
+
if (offset >= hw->eeprom.word_size) {
status = IXGBE_ERR_EEPROM;
goto out;
}
- eewr = (offset << IXGBE_EEPROM_RW_ADDR_SHIFT) |
- (data << IXGBE_EEPROM_RW_REG_DATA) | IXGBE_EEPROM_RW_REG_START;
+ for (i = 0; i < words; i++) {
+ eewr = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) |
+ (data[i] << IXGBE_EEPROM_RW_REG_DATA) |
+ IXGBE_EEPROM_RW_REG_START;
- status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE);
- if (status != 0) {
- hw_dbg(hw, "Eeprom write EEWR timed out\n");
- goto out;
- }
+ status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE);
+ if (status != 0) {
+ hw_dbg(hw, "Eeprom write EEWR timed out\n");
+ goto out;
+ }
- IXGBE_WRITE_REG(hw, IXGBE_EEWR, eewr);
+ IXGBE_WRITE_REG(hw, IXGBE_EEWR, eewr);
- status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE);
- if (status != 0) {
- hw_dbg(hw, "Eeprom write EEWR timed out\n");
- goto out;
+ status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE);
+ if (status != 0) {
+ hw_dbg(hw, "Eeprom write EEWR timed out\n");
+ goto out;
+ }
}
out:
@@ -820,6 +1069,19 @@ out:
}
/**
+ * ixgbe_write_eewr_generic - Write EEPROM word using EEWR
+ * @hw: pointer to hardware structure
+ * @offset: offset of word in the EEPROM to write
+ * @data: word write to the EEPROM
+ *
+ * Write a 16 bit word to the EEPROM using the EEWR register.
+ **/
+s32 ixgbe_write_eewr_generic(struct ixgbe_hw *hw, u16 offset, u16 data)
+{
+ return ixgbe_write_eewr_buffer_generic(hw, offset, 1, &data);
+}
+
+/**
* ixgbe_poll_eerd_eewr_done - Poll EERD read or EEWR write status
* @hw: pointer to hardware structure
* @ee_reg: EEPROM flag for polling
diff --git a/drivers/net/ixgbe/ixgbe_common.h b/drivers/net/ixgbe/ixgbe_common.h
index e850adb..46be83c 100644
--- a/drivers/net/ixgbe/ixgbe_common.h
+++ b/drivers/net/ixgbe/ixgbe_common.h
@@ -49,10 +49,18 @@ s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index);
s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw);
s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data);
+s32 ixgbe_write_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
+ u16 words, u16 *data);
s32 ixgbe_read_eerd_generic(struct ixgbe_hw *hw, u16 offset, u16 *data);
+s32 ixgbe_read_eerd_buffer_generic(struct ixgbe_hw *hw, u16 offset,
+ u16 words, u16 *data);
s32 ixgbe_write_eewr_generic(struct ixgbe_hw *hw, u16 offset, u16 data);
+s32 ixgbe_write_eewr_buffer_generic(struct ixgbe_hw *hw, u16 offset,
+ u16 words, u16 *data);
s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
u16 *data);
+s32 ixgbe_read_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
+ u16 words, u16 *data);
u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw);
s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw,
u16 *checksum_val);
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index 410c298..f2efa32 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -847,11 +847,8 @@ static int ixgbe_get_eeprom(struct net_device *netdev,
if (!eeprom_buff)
return -ENOMEM;
- for (i = 0; i < eeprom_len; i++) {
- if ((ret_val = hw->eeprom.ops.read(hw, first_word + i,
- &eeprom_buff[i])))
- break;
- }
+ ret_val = hw->eeprom.ops.read_buffer(hw, first_word, eeprom_len,
+ eeprom_buff);
/* Device's eeprom is always little-endian, word addressable */
for (i = 0; i < eeprom_len; i++)
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index fab9737..b1d523c 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -1668,6 +1668,10 @@
#define IXGBE_ETH_LENGTH_OF_ADDRESS 6
+#define IXGBE_EEPROM_PAGE_SIZE_MAX 128
+#define IXGBE_EEPROM_RD_BUFFER_MAX_COUNT 512 /* EEPROM words # read in burst */
+#define IXGBE_EEPROM_WR_BUFFER_MAX_COUNT 256 /* EEPROM words # wr in burst */
+
#ifndef IXGBE_EEPROM_GRANT_ATTEMPTS
#define IXGBE_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM # attempts to gain grant */
#endif
@@ -2563,7 +2567,9 @@ typedef u8* (*ixgbe_mc_addr_itr) (struct ixgbe_hw *hw, u8 **mc_addr_ptr,
struct ixgbe_eeprom_operations {
s32 (*init_params)(struct ixgbe_hw *);
s32 (*read)(struct ixgbe_hw *, u16, u16 *);
+ s32 (*read_buffer)(struct ixgbe_hw *, u16, u16, u16 *);
s32 (*write)(struct ixgbe_hw *, u16, u16);
+ s32 (*write_buffer)(struct ixgbe_hw *, u16, u16, u16 *);
s32 (*validate_checksum)(struct ixgbe_hw *, u16 *);
s32 (*update_checksum)(struct ixgbe_hw *);
u16 (*calc_checksum)(struct ixgbe_hw *);
@@ -2649,6 +2655,7 @@ struct ixgbe_eeprom_info {
u32 semaphore_delay;
u16 word_size;
u16 address_bits;
+ u16 word_page_size;
};
#define IXGBE_FLAGS_DOUBLE_RESET_REQUIRED 0x01
diff --git a/drivers/net/ixgbe/ixgbe_x540.c b/drivers/net/ixgbe/ixgbe_x540.c
index 179ee82..4ed687b 100644
--- a/drivers/net/ixgbe/ixgbe_x540.c
+++ b/drivers/net/ixgbe/ixgbe_x540.c
@@ -304,16 +304,19 @@ static s32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw)
}
/**
- * ixgbe_read_eerd_X540 - Read EEPROM word using EERD
- * @hw: pointer to hardware structure
- * @offset: offset of word in the EEPROM to read
- * @data: word read from the EERPOM
+ * ixgbe_read_eerd_X540- Read EEPROM word using EERD
+ * @hw: pointer to hardware structure
+ * @offset: offset of word in the EEPROM to read
+ * @data: word read from the EEPROM
+ *
+ * Reads a 16 bit word from the EEPROM using the EERD register.
**/
static s32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data)
{
- s32 status;
+ s32 status = 0;
- if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0)
+ if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
+ 0)
status = ixgbe_read_eerd_generic(hw, offset, data);
else
status = IXGBE_ERR_SWFW_SYNC;
@@ -323,6 +326,31 @@ static s32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data)
}
/**
+ * ixgbe_read_eerd_buffer_X540 - Read EEPROM word(s) using EERD
+ * @hw: pointer to hardware structure
+ * @offset: offset of word in the EEPROM to read
+ * @words: number of words
+ * @data: word(s) read from the EEPROM
+ *
+ * Reads a 16 bit word(s) from the EEPROM using the EERD register.
+ **/
+static s32 ixgbe_read_eerd_buffer_X540(struct ixgbe_hw *hw,
+ u16 offset, u16 words, u16 *data)
+{
+ s32 status = 0;
+
+ if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
+ 0)
+ status = ixgbe_read_eerd_buffer_generic(hw, offset,
+ words, data);
+ else
+ status = IXGBE_ERR_SWFW_SYNC;
+
+ hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
+ return status;
+}
+
+/**
* ixgbe_write_eewr_X540 - Write EEPROM word using EEWR
* @hw: pointer to hardware structure
* @offset: offset of word in the EEPROM to write
@@ -344,6 +372,31 @@ static s32 ixgbe_write_eewr_X540(struct ixgbe_hw *hw, u16 offset, u16 data)
}
/**
+ * ixgbe_write_eewr_buffer_X540 - Write EEPROM word(s) using EEWR
+ * @hw: pointer to hardware structure
+ * @offset: offset of word in the EEPROM to write
+ * @words: number of words
+ * @data: word(s) write to the EEPROM
+ *
+ * Write a 16 bit word(s) to the EEPROM using the EEWR register.
+ **/
+static s32 ixgbe_write_eewr_buffer_X540(struct ixgbe_hw *hw,
+ u16 offset, u16 words, u16 *data)
+{
+ s32 status = 0;
+
+ if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
+ 0)
+ status = ixgbe_write_eewr_buffer_generic(hw, offset,
+ words, data);
+ else
+ status = IXGBE_ERR_SWFW_SYNC;
+
+ hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
+ return status;
+}
+
+/**
* ixgbe_calc_eeprom_checksum_X540 - Calculates and returns the checksum
*
* This function does not use synchronization for EERD and EEWR. It can
@@ -851,7 +904,9 @@ static struct ixgbe_mac_operations mac_ops_X540 = {
static struct ixgbe_eeprom_operations eeprom_ops_X540 = {
.init_params = &ixgbe_init_eeprom_params_X540,
.read = &ixgbe_read_eerd_X540,
+ .read_buffer = &ixgbe_read_eerd_buffer_X540,
.write = &ixgbe_write_eewr_X540,
+ .write_buffer = &ixgbe_write_eewr_buffer_X540,
.calc_checksum = &ixgbe_calc_eeprom_checksum_X540,
.validate_checksum = &ixgbe_validate_eeprom_checksum_X540,
.update_checksum = &ixgbe_update_eeprom_checksum_X540,
--
1.7.4.4
^ permalink raw reply related
* Re: Divide error in bictcp_cong_avoid ?
From: Valdis.Kletnieks @ 2011-05-04 19:31 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: Randy Dunlap, TB, netdev, linux-kernel
In-Reply-To: <20110504113351.4643a0c9@nehalam>
[-- Attachment #1: Type: text/plain, Size: 697 bytes --]
On Wed, 04 May 2011 11:33:51 PDT, Stephen Hemminger said:
> What kernel version? I suspect they are running something really old
> kernel like RHEL 5 since BIC has not been the default congestion control for
> several years.
Pretty bleeding edge here, and BIC is *still* the default:
% uname -a
Linux turing-police.cc.vt.edu 2.6.39-rc5-mmotm0429 #1 SMP PREEMPT Sat Apr 30 00:36:49 EDT 2011 x86_64 x86_64 x86_64 GNU/Linux
% zgrep -i BIC /proc/config.gz
CONFIG_TCP_CONG_BIC=y
CONFIG_TCP_CONG_CUBIC=m
CONFIG_DEFAULT_BIC=y
CONFIG_DEFAULT_TCP_CONG="bic"
Why? Because BIC was working "well enough", so I never changed it by hand, and
"make oldconfig" never changed it automagically either. Now,
[-- Attachment #2: Type: application/pgp-signature, Size: 227 bytes --]
^ permalink raw reply
* Re: Divide error in bictcp_cong_avoid ?
From: Stephen Hemminger @ 2011-05-04 19:37 UTC (permalink / raw)
To: Valdis.Kletnieks; +Cc: Randy Dunlap, TB, netdev, linux-kernel
In-Reply-To: <16668.1304537481@localhost>
On Wed, 04 May 2011 15:31:21 -0400
Valdis.Kletnieks@vt.edu wrote:
> On Wed, 04 May 2011 11:33:51 PDT, Stephen Hemminger said:
>
> > What kernel version? I suspect they are running something really old
> > kernel like RHEL 5 since BIC has not been the default congestion control for
> > several years.
>
> Pretty bleeding edge here, and BIC is *still* the default:
>
> % uname -a
> Linux turing-police.cc.vt.edu 2.6.39-rc5-mmotm0429 #1 SMP PREEMPT Sat Apr 30 00:36:49 EDT 2011 x86_64 x86_64 x86_64 GNU/Linux
> % zgrep -i BIC /proc/config.gz
> CONFIG_TCP_CONG_BIC=y
> CONFIG_TCP_CONG_CUBIC=m
> CONFIG_DEFAULT_BIC=y
> CONFIG_DEFAULT_TCP_CONG="bic"
>
> Why? Because BIC was working "well enough", so I never changed it by hand, and
> "make oldconfig" never changed it automagically either. Now,
>
The CUBIC code has the same function names so that is where the
problem is.
Don't use BIC, it is known to be unfair between flows.
The configuration process never changes your values, it only asks
about new ones.
--
^ permalink raw reply
* Re: [PATCH 1/2] libertas: Convert lbs_pr_<level> to pr_<level>
From: Dan Williams @ 2011-05-04 19:39 UTC (permalink / raw)
To: Joe Perches
Cc: John W. Linville, libertas-dev-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <353dfb1607172b5a3dbaccddbe52c24312d42af4.1304379925.git.joe-6d6DIl74uiNBDgjK7y7TUQ@public.gmane.org>
On Mon, 2011-05-02 at 16:49 -0700, Joe Perches wrote:
> Use the standard pr_<level> functions eases grep a bit.
>
> Added a few missing terminating newlines to messages.
> Coalesced long formats.
Is there any reason to not put the pr_fmt() definition into 'defs.h'
instead of C&P at the top of every file? I don't really care either way
but that seems cleaner since almost all the libertas files are going to
use logging.
Dan
> Signed-off-by: Joe Perches <joe-6d6DIl74uiNBDgjK7y7TUQ@public.gmane.org>
> ---
> drivers/net/wireless/libertas/cfg.c | 15 +++---
> drivers/net/wireless/libertas/cmd.c | 36 +++++++-------
> drivers/net/wireless/libertas/cmdresp.c | 29 +++++++-----
> drivers/net/wireless/libertas/debugfs.c | 6 ++-
> drivers/net/wireless/libertas/defs.h | 7 ---
> drivers/net/wireless/libertas/if_cs.c | 52 +++++++++++----------
> drivers/net/wireless/libertas/if_sdio.c | 38 ++++++++--------
> drivers/net/wireless/libertas/if_spi.c | 74 ++++++++++++++-----------------
> drivers/net/wireless/libertas/if_usb.c | 41 +++++++++--------
> drivers/net/wireless/libertas/main.c | 33 +++++++-------
> drivers/net/wireless/libertas/mesh.c | 8 ++-
> drivers/net/wireless/libertas/rx.c | 7 ++-
> 12 files changed, 174 insertions(+), 172 deletions(-)
>
> diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
> index 5caa2ac..d6e0656 100644
> --- a/drivers/net/wireless/libertas/cfg.c
> +++ b/drivers/net/wireless/libertas/cfg.c
> @@ -6,6 +6,8 @@
> *
> */
>
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +
> #include <linux/sched.h>
> #include <linux/wait.h>
> #include <linux/slab.h>
> @@ -1314,8 +1316,7 @@ static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev,
> sme->ssid, sme->ssid_len,
> WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
> if (!bss) {
> - lbs_pr_err("assoc: bss %pM not in scan results\n",
> - sme->bssid);
> + pr_err("assoc: bss %pM not in scan results\n", sme->bssid);
> ret = -ENOENT;
> goto done;
> }
> @@ -1372,8 +1373,8 @@ static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev,
> lbs_enable_rsn(priv, sme->crypto.cipher_group != 0);
> break;
> default:
> - lbs_pr_err("unsupported cipher group 0x%x\n",
> - sme->crypto.cipher_group);
> + pr_err("unsupported cipher group 0x%x\n",
> + sme->crypto.cipher_group);
> ret = -ENOTSUPP;
> goto done;
> }
> @@ -1491,7 +1492,7 @@ static int lbs_cfg_add_key(struct wiphy *wiphy, struct net_device *netdev,
> params->key, params->key_len);
> break;
> default:
> - lbs_pr_err("unhandled cipher 0x%x\n", params->cipher);
> + pr_err("unhandled cipher 0x%x\n", params->cipher);
> ret = -ENOTSUPP;
> break;
> }
> @@ -2118,13 +2119,13 @@ int lbs_cfg_register(struct lbs_private *priv)
>
> ret = wiphy_register(wdev->wiphy);
> if (ret < 0)
> - lbs_pr_err("cannot register wiphy device\n");
> + pr_err("cannot register wiphy device\n");
>
> priv->wiphy_registered = true;
>
> ret = register_netdev(priv->dev);
> if (ret)
> - lbs_pr_err("cannot register network device\n");
> + pr_err("cannot register network device\n");
>
> INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker);
>
> diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
> index 7e8a658..10ca485 100644
> --- a/drivers/net/wireless/libertas/cmd.c
> +++ b/drivers/net/wireless/libertas/cmd.c
> @@ -3,6 +3,8 @@
> * It prepares command and sends it to firmware when it is ready.
> */
>
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +
> #include <linux/kfifo.h>
> #include <linux/sched.h>
> #include <linux/slab.h>
> @@ -108,7 +110,7 @@ int lbs_update_hw_spec(struct lbs_private *priv)
> * CF card firmware 5.0.16p0: cap 0x00000303
> * USB dongle firmware 5.110.17p2: cap 0x00000303
> */
> - lbs_pr_info("%pM, fw %u.%u.%up%u, cap 0x%08x\n",
> + pr_info("%pM, fw %u.%u.%up%u, cap 0x%08x\n",
> cmd.permanentaddr,
> priv->fwrelease >> 24 & 0xff,
> priv->fwrelease >> 16 & 0xff,
> @@ -139,7 +141,7 @@ int lbs_update_hw_spec(struct lbs_private *priv)
> /* if it's unidentified region code, use the default (USA) */
> if (i >= MRVDRV_MAX_REGION_CODE) {
> priv->regioncode = 0x10;
> - lbs_pr_info("unidentified region code; using the default (USA)\n");
> + pr_info("unidentified region code; using the default (USA)\n");
> }
>
> if (priv->current_addr[0] == 0xff)
> @@ -209,7 +211,7 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
> (uint8_t *)&cmd_config.wol_conf,
> sizeof(struct wol_config));
> } else {
> - lbs_pr_info("HOST_SLEEP_CFG failed %d\n", ret);
> + pr_info("HOST_SLEEP_CFG failed %d\n", ret);
> }
>
> return ret;
> @@ -312,7 +314,7 @@ static int lbs_wait_for_ds_awake(struct lbs_private *priv)
> if (priv->is_deep_sleep) {
> if (!wait_event_interruptible_timeout(priv->ds_awake_q,
> !priv->is_deep_sleep, (10 * HZ))) {
> - lbs_pr_err("ds_awake_q: timer expired\n");
> + pr_err("ds_awake_q: timer expired\n");
> ret = -1;
> }
> }
> @@ -337,7 +339,7 @@ int lbs_set_deep_sleep(struct lbs_private *priv, int deep_sleep)
> netif_carrier_off(priv->dev);
> }
> } else {
> - lbs_pr_err("deep sleep: already enabled\n");
> + pr_err("deep sleep: already enabled\n");
> }
> } else {
> if (priv->is_deep_sleep) {
> @@ -347,8 +349,7 @@ int lbs_set_deep_sleep(struct lbs_private *priv, int deep_sleep)
> if (!ret) {
> ret = lbs_wait_for_ds_awake(priv);
> if (ret)
> - lbs_pr_err("deep sleep: wakeup"
> - "failed\n");
> + pr_err("deep sleep: wakeup failed\n");
> }
> }
> }
> @@ -382,8 +383,8 @@ int lbs_set_host_sleep(struct lbs_private *priv, int host_sleep)
> ret = lbs_host_sleep_cfg(priv, priv->wol_criteria,
> (struct wol_config *)NULL);
> if (ret) {
> - lbs_pr_info("Host sleep configuration failed: "
> - "%d\n", ret);
> + pr_info("Host sleep configuration failed: %d\n",
> + ret);
> return ret;
> }
> if (priv->psstate == PS_STATE_FULL_POWER) {
> @@ -393,19 +394,19 @@ int lbs_set_host_sleep(struct lbs_private *priv, int host_sleep)
> sizeof(cmd),
> lbs_ret_host_sleep_activate, 0);
> if (ret)
> - lbs_pr_info("HOST_SLEEP_ACTIVATE "
> - "failed: %d\n", ret);
> + pr_info("HOST_SLEEP_ACTIVATE failed: %d\n",
> + ret);
> }
>
> if (!wait_event_interruptible_timeout(
> priv->host_sleep_q,
> priv->is_host_sleep_activated,
> (10 * HZ))) {
> - lbs_pr_err("host_sleep_q: timer expired\n");
> + pr_err("host_sleep_q: timer expired\n");
> ret = -1;
> }
> } else {
> - lbs_pr_err("host sleep: already enabled\n");
> + pr_err("host sleep: already enabled\n");
> }
> } else {
> if (priv->is_host_sleep_activated)
> @@ -1002,7 +1003,7 @@ static void lbs_submit_command(struct lbs_private *priv,
> ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize);
>
> if (ret) {
> - lbs_pr_info("DNLD_CMD: hw_host_to_card failed: %d\n", ret);
> + pr_info("DNLD_CMD: hw_host_to_card failed: %d\n", ret);
> /* Let the timer kick in and retry, and potentially reset
> the whole thing if the condition persists */
> timeo = HZ/4;
> @@ -1267,7 +1268,7 @@ int lbs_execute_next_command(struct lbs_private *priv)
> spin_lock_irqsave(&priv->driver_lock, flags);
>
> if (priv->cur_cmd) {
> - lbs_pr_alert( "EXEC_NEXT_CMD: already processing command!\n");
> + pr_alert( "EXEC_NEXT_CMD: already processing command!\n");
> spin_unlock_irqrestore(&priv->driver_lock, flags);
> ret = -1;
> goto done;
> @@ -1429,7 +1430,7 @@ static void lbs_send_confirmsleep(struct lbs_private *priv)
> ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) &confirm_sleep,
> sizeof(confirm_sleep));
> if (ret) {
> - lbs_pr_alert("confirm_sleep failed\n");
> + pr_alert("confirm_sleep failed\n");
> goto out;
> }
>
> @@ -1655,8 +1656,7 @@ int __lbs_cmd(struct lbs_private *priv, uint16_t command,
> spin_lock_irqsave(&priv->driver_lock, flags);
> ret = cmdnode->result;
> if (ret)
> - lbs_pr_info("PREP_CMD: command 0x%04x failed: %d\n",
> - command, ret);
> + pr_info("PREP_CMD: command 0x%04x failed: %d\n", command, ret);
>
> __lbs_cleanup_and_insert_cmd(priv, cmdnode);
> spin_unlock_irqrestore(&priv->driver_lock, flags);
> diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c
> index 5e95da9..2cb6f5f 100644
> --- a/drivers/net/wireless/libertas/cmdresp.c
> +++ b/drivers/net/wireless/libertas/cmdresp.c
> @@ -2,6 +2,9 @@
> * This file contains the handling of command
> * responses as well as events generated by firmware.
> */
> +
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +
> #include <linux/slab.h>
> #include <linux/delay.h>
> #include <linux/sched.h>
> @@ -84,15 +87,17 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len)
> lbs_deb_hex(LBS_DEB_CMD, "CMD_RESP", (void *) resp, len);
>
> if (resp->seqnum != priv->cur_cmd->cmdbuf->seqnum) {
> - lbs_pr_info("Received CMD_RESP with invalid sequence %d (expected %d)\n",
> - le16_to_cpu(resp->seqnum), le16_to_cpu(priv->cur_cmd->cmdbuf->seqnum));
> + pr_info("Received CMD_RESP with invalid sequence %d (expected %d)\n",
> + le16_to_cpu(resp->seqnum),
> + le16_to_cpu(priv->cur_cmd->cmdbuf->seqnum));
> spin_unlock_irqrestore(&priv->driver_lock, flags);
> ret = -1;
> goto done;
> }
> if (respcmd != CMD_RET(curcmd) &&
> respcmd != CMD_RET_802_11_ASSOCIATE && curcmd != CMD_802_11_ASSOCIATE) {
> - lbs_pr_info("Invalid CMD_RESP %x to command %x!\n", respcmd, curcmd);
> + pr_info("Invalid CMD_RESP %x to command %x!\n",
> + respcmd, curcmd);
> spin_unlock_irqrestore(&priv->driver_lock, flags);
> ret = -1;
> goto done;
> @@ -101,8 +106,8 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len)
> if (resp->result == cpu_to_le16(0x0004)) {
> /* 0x0004 means -EAGAIN. Drop the response, let it time out
> and be resubmitted */
> - lbs_pr_info("Firmware returns DEFER to command %x. Will let it time out...\n",
> - le16_to_cpu(resp->command));
> + pr_info("Firmware returns DEFER to command %x. Will let it time out...\n",
> + le16_to_cpu(resp->command));
> spin_unlock_irqrestore(&priv->driver_lock, flags);
> ret = -1;
> goto done;
> @@ -313,28 +318,28 @@ int lbs_process_event(struct lbs_private *priv, u32 event)
> lbs_deb_cmd("EVENT: ADHOC beacon lost\n");
> break;
> case MACREG_INT_CODE_RSSI_LOW:
> - lbs_pr_alert("EVENT: rssi low\n");
> + pr_alert("EVENT: rssi low\n");
> break;
> case MACREG_INT_CODE_SNR_LOW:
> - lbs_pr_alert("EVENT: snr low\n");
> + pr_alert("EVENT: snr low\n");
> break;
> case MACREG_INT_CODE_MAX_FAIL:
> - lbs_pr_alert("EVENT: max fail\n");
> + pr_alert("EVENT: max fail\n");
> break;
> case MACREG_INT_CODE_RSSI_HIGH:
> - lbs_pr_alert("EVENT: rssi high\n");
> + pr_alert("EVENT: rssi high\n");
> break;
> case MACREG_INT_CODE_SNR_HIGH:
> - lbs_pr_alert("EVENT: snr high\n");
> + pr_alert("EVENT: snr high\n");
> break;
>
> case MACREG_INT_CODE_MESH_AUTO_STARTED:
> /* Ignore spurious autostart events */
> - lbs_pr_info("EVENT: MESH_AUTO_STARTED (ignoring)\n");
> + pr_info("EVENT: MESH_AUTO_STARTED (ignoring)\n");
> break;
>
> default:
> - lbs_pr_alert("EVENT: unknown event id %d\n", event);
> + pr_alert("EVENT: unknown event id %d\n", event);
> break;
> }
>
> diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c
> index fbf3b033..c179094 100644
> --- a/drivers/net/wireless/libertas/debugfs.c
> +++ b/drivers/net/wireless/libertas/debugfs.c
> @@ -1,3 +1,5 @@
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +
> #include <linux/dcache.h>
> #include <linux/debugfs.h>
> #include <linux/delay.h>
> @@ -151,13 +153,13 @@ static ssize_t lbs_host_sleep_write(struct file *file,
> ret = lbs_set_host_sleep(priv, 0);
> else if (host_sleep == 1) {
> if (priv->wol_criteria == EHS_REMOVE_WAKEUP) {
> - lbs_pr_info("wake parameters not configured");
> + pr_info("wake parameters not configured\n");
> ret = -EINVAL;
> goto out_unlock;
> }
> ret = lbs_set_host_sleep(priv, 1);
> } else {
> - lbs_pr_err("invalid option\n");
> + pr_err("invalid option\n");
> ret = -EINVAL;
> }
>
> diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h
> index d00c728..c9b89b0 100644
> --- a/drivers/net/wireless/libertas/defs.h
> +++ b/drivers/net/wireless/libertas/defs.h
> @@ -89,13 +89,6 @@ do { if ((lbs_debug & (grp)) == (grp)) \
> #define lbs_deb_spi(fmt, args...) LBS_DEB_LL(LBS_DEB_SPI, " spi", fmt, ##args)
> #define lbs_deb_cfg80211(fmt, args...) LBS_DEB_LL(LBS_DEB_CFG80211, " cfg80211", fmt, ##args)
>
> -#define lbs_pr_info(format, args...) \
> - printk(KERN_INFO DRV_NAME": " format, ## args)
> -#define lbs_pr_err(format, args...) \
> - printk(KERN_ERR DRV_NAME": " format, ## args)
> -#define lbs_pr_alert(format, args...) \
> - printk(KERN_ALERT DRV_NAME": " format, ## args)
> -
> #ifdef DEBUG
> static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, int len)
> {
> diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
> index 8712cb2..eb88d9a 100644
> --- a/drivers/net/wireless/libertas/if_cs.c
> +++ b/drivers/net/wireless/libertas/if_cs.c
> @@ -21,6 +21,8 @@
>
> */
>
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +
> #include <linux/module.h>
> #include <linux/slab.h>
> #include <linux/delay.h>
> @@ -361,7 +363,7 @@ static int if_cs_send_cmd(struct lbs_private *priv, u8 *buf, u16 nb)
> if (status & IF_CS_BIT_COMMAND)
> break;
> if (++loops > 100) {
> - lbs_pr_err("card not ready for commands\n");
> + pr_err("card not ready for commands\n");
> goto done;
> }
> mdelay(1);
> @@ -431,14 +433,14 @@ static int if_cs_receive_cmdres(struct lbs_private *priv, u8 *data, u32 *len)
> /* is hardware ready? */
> status = if_cs_read16(priv->card, IF_CS_CARD_STATUS);
> if ((status & IF_CS_BIT_RESP) == 0) {
> - lbs_pr_err("no cmd response in card\n");
> + pr_err("no cmd response in card\n");
> *len = 0;
> goto out;
> }
>
> *len = if_cs_read16(priv->card, IF_CS_RESP_LEN);
> if ((*len == 0) || (*len > LBS_CMD_BUFFER_SIZE)) {
> - lbs_pr_err("card cmd buffer has invalid # of bytes (%d)\n", *len);
> + pr_err("card cmd buffer has invalid # of bytes (%d)\n", *len);
> goto out;
> }
>
> @@ -472,7 +474,7 @@ static struct sk_buff *if_cs_receive_data(struct lbs_private *priv)
>
> len = if_cs_read16(priv->card, IF_CS_READ_LEN);
> if (len == 0 || len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) {
> - lbs_pr_err("card data buffer has invalid # of bytes (%d)\n", len);
> + pr_err("card data buffer has invalid # of bytes (%d)\n", len);
> priv->dev->stats.rx_dropped++;
> goto dat_err;
> }
> @@ -644,8 +646,8 @@ static int if_cs_prog_helper(struct if_cs_card *card, const struct firmware *fw)
> ret = if_cs_poll_while_fw_download(card, IF_CS_CARD_STATUS,
> IF_CS_BIT_COMMAND);
> if (ret < 0) {
> - lbs_pr_err("can't download helper at 0x%x, ret %d\n",
> - sent, ret);
> + pr_err("can't download helper at 0x%x, ret %d\n",
> + sent, ret);
> goto done;
> }
>
> @@ -675,7 +677,7 @@ static int if_cs_prog_real(struct if_cs_card *card, const struct firmware *fw)
> ret = if_cs_poll_while_fw_download(card, IF_CS_SQ_READ_LOW,
> IF_CS_SQ_HELPER_OK);
> if (ret < 0) {
> - lbs_pr_err("helper firmware doesn't answer\n");
> + pr_err("helper firmware doesn't answer\n");
> goto done;
> }
>
> @@ -683,13 +685,13 @@ static int if_cs_prog_real(struct if_cs_card *card, const struct firmware *fw)
> len = if_cs_read16(card, IF_CS_SQ_READ_LOW);
> if (len & 1) {
> retry++;
> - lbs_pr_info("odd, need to retry this firmware block\n");
> + pr_info("odd, need to retry this firmware block\n");
> } else {
> retry = 0;
> }
>
> if (retry > 20) {
> - lbs_pr_err("could not download firmware\n");
> + pr_err("could not download firmware\n");
> ret = -ENODEV;
> goto done;
> }
> @@ -709,14 +711,14 @@ static int if_cs_prog_real(struct if_cs_card *card, const struct firmware *fw)
> ret = if_cs_poll_while_fw_download(card, IF_CS_CARD_STATUS,
> IF_CS_BIT_COMMAND);
> if (ret < 0) {
> - lbs_pr_err("can't download firmware at 0x%x\n", sent);
> + pr_err("can't download firmware at 0x%x\n", sent);
> goto done;
> }
> }
>
> ret = if_cs_poll_while_fw_download(card, IF_CS_SCRATCH, 0x5a);
> if (ret < 0)
> - lbs_pr_err("firmware download failed\n");
> + pr_err("firmware download failed\n");
>
> done:
> lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
> @@ -750,7 +752,7 @@ static int if_cs_host_to_card(struct lbs_private *priv,
> ret = if_cs_send_cmd(priv, buf, nb);
> break;
> default:
> - lbs_pr_err("%s: unsupported type %d\n", __func__, type);
> + pr_err("%s: unsupported type %d\n", __func__, type);
> }
>
> lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
> @@ -779,7 +781,7 @@ static int if_cs_ioprobe(struct pcmcia_device *p_dev, void *priv_data)
> p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
>
> if (p_dev->resource[1]->end) {
> - lbs_pr_err("wrong CIS (check number of IO windows)\n");
> + pr_err("wrong CIS (check number of IO windows)\n");
> return -ENODEV;
> }
>
> @@ -800,7 +802,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
>
> card = kzalloc(sizeof(struct if_cs_card), GFP_KERNEL);
> if (!card) {
> - lbs_pr_err("error in kzalloc\n");
> + pr_err("error in kzalloc\n");
> goto out;
> }
> card->p_dev = p_dev;
> @@ -809,7 +811,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
> p_dev->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
>
> if (pcmcia_loop_config(p_dev, if_cs_ioprobe, NULL)) {
> - lbs_pr_err("error in pcmcia_loop_config\n");
> + pr_err("error in pcmcia_loop_config\n");
> goto out1;
> }
>
> @@ -825,14 +827,14 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
> card->iobase = ioport_map(p_dev->resource[0]->start,
> resource_size(p_dev->resource[0]));
> if (!card->iobase) {
> - lbs_pr_err("error in ioport_map\n");
> + pr_err("error in ioport_map\n");
> ret = -EIO;
> goto out1;
> }
>
> ret = pcmcia_enable_device(p_dev);
> if (ret) {
> - lbs_pr_err("error in pcmcia_enable_device\n");
> + pr_err("error in pcmcia_enable_device\n");
> goto out2;
> }
>
> @@ -847,8 +849,8 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
>
> card->model = get_model(p_dev->manf_id, p_dev->card_id);
> if (card->model == MODEL_UNKNOWN) {
> - lbs_pr_err("unsupported manf_id 0x%04x / card_id 0x%04x\n",
> - p_dev->manf_id, p_dev->card_id);
> + pr_err("unsupported manf_id 0x%04x / card_id 0x%04x\n",
> + p_dev->manf_id, p_dev->card_id);
> goto out2;
> }
>
> @@ -857,20 +859,20 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
> if (card->model == MODEL_8305) {
> card->align_regs = 1;
> if (prod_id < IF_CS_CF8305_B1_REV) {
> - lbs_pr_err("8305 rev B0 and older are not supported\n");
> + pr_err("8305 rev B0 and older are not supported\n");
> ret = -ENODEV;
> goto out2;
> }
> }
>
> if ((card->model == MODEL_8381) && prod_id < IF_CS_CF8381_B3_REV) {
> - lbs_pr_err("8381 rev B2 and older are not supported\n");
> + pr_err("8381 rev B2 and older are not supported\n");
> ret = -ENODEV;
> goto out2;
> }
>
> if ((card->model == MODEL_8385) && prod_id < IF_CS_CF8385_B1_REV) {
> - lbs_pr_err("8385 rev B0 and older are not supported\n");
> + pr_err("8385 rev B0 and older are not supported\n");
> ret = -ENODEV;
> goto out2;
> }
> @@ -878,7 +880,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
> ret = lbs_get_firmware(&p_dev->dev, NULL, NULL, card->model,
> &fw_table[0], &helper, &mainfw);
> if (ret) {
> - lbs_pr_err("failed to find firmware (%d)\n", ret);
> + pr_err("failed to find firmware (%d)\n", ret);
> goto out2;
> }
>
> @@ -909,7 +911,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
> ret = request_irq(p_dev->irq, if_cs_interrupt,
> IRQF_SHARED, DRV_NAME, card);
> if (ret) {
> - lbs_pr_err("error in request_irq\n");
> + pr_err("error in request_irq\n");
> goto out3;
> }
>
> @@ -920,7 +922,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
>
> /* And finally bring the card up */
> if (lbs_start_card(priv) != 0) {
> - lbs_pr_err("could not activate card\n");
> + pr_err("could not activate card\n");
> goto out3;
> }
>
> diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
> index b4de0ca..ab86779 100644
> --- a/drivers/net/wireless/libertas/if_sdio.c
> +++ b/drivers/net/wireless/libertas/if_sdio.c
> @@ -26,6 +26,8 @@
> * if_sdio_card_to_host() to pad the data.
> */
>
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +
> #include <linux/kernel.h>
> #include <linux/moduleparam.h>
> #include <linux/slab.h>
> @@ -409,7 +411,7 @@ static int if_sdio_card_to_host(struct if_sdio_card *card)
>
> out:
> if (ret)
> - lbs_pr_err("problem fetching packet from firmware\n");
> + pr_err("problem fetching packet from firmware\n");
>
> lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
>
> @@ -446,7 +448,7 @@ static void if_sdio_host_to_card_worker(struct work_struct *work)
> }
>
> if (ret)
> - lbs_pr_err("error %d sending packet to firmware\n", ret);
> + pr_err("error %d sending packet to firmware\n", ret);
>
> sdio_release_host(card->func);
>
> @@ -555,7 +557,7 @@ release:
>
> out:
> if (ret)
> - lbs_pr_err("failed to load helper firmware\n");
> + pr_err("failed to load helper firmware\n");
>
> lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
> return ret;
> @@ -669,7 +671,7 @@ release:
>
> out:
> if (ret)
> - lbs_pr_err("failed to load firmware\n");
> + pr_err("failed to load firmware\n");
>
> lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
> return ret;
> @@ -723,7 +725,7 @@ static int if_sdio_prog_firmware(struct if_sdio_card *card)
> ret = lbs_get_firmware(&card->func->dev, lbs_helper_name, lbs_fw_name,
> card->model, &fw_table[0], &helper, &mainfw);
> if (ret) {
> - lbs_pr_err("failed to find firmware (%d)\n", ret);
> + pr_err("failed to find firmware (%d)\n", ret);
> goto out;
> }
>
> @@ -849,7 +851,7 @@ static int if_sdio_enter_deep_sleep(struct lbs_private *priv)
> ret = __lbs_cmd(priv, CMD_802_11_DEEP_SLEEP, &cmd, sizeof(cmd),
> lbs_cmd_copyback, (unsigned long) &cmd);
> if (ret)
> - lbs_pr_err("DEEP_SLEEP cmd failed\n");
> + pr_err("DEEP_SLEEP cmd failed\n");
>
> mdelay(200);
> return ret;
> @@ -865,7 +867,7 @@ static int if_sdio_exit_deep_sleep(struct lbs_private *priv)
>
> sdio_writeb(card->func, HOST_POWER_UP, CONFIGURATION_REG, &ret);
> if (ret)
> - lbs_pr_err("sdio_writeb failed!\n");
> + pr_err("sdio_writeb failed!\n");
>
> sdio_release_host(card->func);
> lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
> @@ -882,7 +884,7 @@ static int if_sdio_reset_deep_sleep_wakeup(struct lbs_private *priv)
>
> sdio_writeb(card->func, 0, CONFIGURATION_REG, &ret);
> if (ret)
> - lbs_pr_err("sdio_writeb failed!\n");
> + pr_err("sdio_writeb failed!\n");
>
> sdio_release_host(card->func);
> lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
> @@ -961,7 +963,7 @@ static int if_sdio_probe(struct sdio_func *func,
> }
>
> if (i == func->card->num_info) {
> - lbs_pr_err("unable to identify card model\n");
> + pr_err("unable to identify card model\n");
> return -ENODEV;
> }
>
> @@ -995,7 +997,7 @@ static int if_sdio_probe(struct sdio_func *func,
> break;
> }
> if (i == ARRAY_SIZE(fw_table)) {
> - lbs_pr_err("unknown card model 0x%x\n", card->model);
> + pr_err("unknown card model 0x%x\n", card->model);
> ret = -ENODEV;
> goto free;
> }
> @@ -1101,7 +1103,7 @@ static int if_sdio_probe(struct sdio_func *func,
> lbs_deb_sdio("send function INIT command\n");
> if (__lbs_cmd(priv, CMD_FUNC_INIT, &cmd, sizeof(cmd),
> lbs_cmd_copyback, (unsigned long) &cmd))
> - lbs_pr_alert("CMD_FUNC_INIT cmd failed\n");
> + pr_alert("CMD_FUNC_INIT cmd failed\n");
> }
>
> ret = lbs_start_card(priv);
> @@ -1163,7 +1165,7 @@ static void if_sdio_remove(struct sdio_func *func)
> if (__lbs_cmd(card->priv, CMD_FUNC_SHUTDOWN,
> &cmd, sizeof(cmd), lbs_cmd_copyback,
> (unsigned long) &cmd))
> - lbs_pr_alert("CMD_FUNC_SHUTDOWN cmd failed\n");
> + pr_alert("CMD_FUNC_SHUTDOWN cmd failed\n");
> }
>
>
> @@ -1202,21 +1204,19 @@ static int if_sdio_suspend(struct device *dev)
>
> mmc_pm_flag_t flags = sdio_get_host_pm_caps(func);
>
> - lbs_pr_info("%s: suspend: PM flags = 0x%x\n",
> - sdio_func_id(func), flags);
> + pr_info("%s: suspend: PM flags = 0x%x\n", sdio_func_id(func), flags);
>
> /* If we aren't being asked to wake on anything, we should bail out
> * and let the SD stack power down the card.
> */
> if (card->priv->wol_criteria == EHS_REMOVE_WAKEUP) {
> - lbs_pr_info("Suspend without wake params -- "
> - "powering down card.");
> + pr_info("Suspend without wake params -- powering down card\n");
> return -ENOSYS;
> }
>
> if (!(flags & MMC_PM_KEEP_POWER)) {
> - lbs_pr_err("%s: cannot remain alive while host is suspended\n",
> - sdio_func_id(func));
> + pr_err("%s: cannot remain alive while host is suspended\n",
> + sdio_func_id(func));
> return -ENOSYS;
> }
>
> @@ -1237,7 +1237,7 @@ static int if_sdio_resume(struct device *dev)
> struct if_sdio_card *card = sdio_get_drvdata(func);
> int ret;
>
> - lbs_pr_info("%s: resume: we're back\n", sdio_func_id(func));
> + pr_info("%s: resume: we're back\n", sdio_func_id(func));
>
> ret = lbs_resume(card->priv);
>
> diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c
> index 078ef43..bebd9f0 100644
> --- a/drivers/net/wireless/libertas/if_spi.c
> +++ b/drivers/net/wireless/libertas/if_spi.c
> @@ -17,6 +17,8 @@
> * (at your option) any later version.
> */
>
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +
> #include <linux/moduleparam.h>
> #include <linux/firmware.h>
> #include <linux/jiffies.h>
> @@ -297,8 +299,7 @@ static int spu_wait_for_u16(struct if_spi_card *card, u16 reg,
> }
> udelay(100);
> if (time_after(jiffies, timeout)) {
> - lbs_pr_err("%s: timeout with val=%02x, "
> - "target_mask=%02x, target=%02x\n",
> + pr_err("%s: timeout with val=%02x, target_mask=%02x, target=%02x\n",
> __func__, val, target_mask, target);
> return -ETIMEDOUT;
> }
> @@ -391,7 +392,7 @@ static int spu_set_bus_mode(struct if_spi_card *card, u16 mode)
> if (err)
> return err;
> if ((rval & 0xF) != mode) {
> - lbs_pr_err("Can't read bus mode register.\n");
> + pr_err("Can't read bus mode register\n");
> return -EIO;
> }
> return 0;
> @@ -512,7 +513,7 @@ static int if_spi_prog_helper_firmware(struct if_spi_card *card,
>
> out:
> if (err)
> - lbs_pr_err("failed to load helper firmware (err=%d)\n", err);
> + pr_err("failed to load helper firmware (err=%d)\n", err);
> lbs_deb_leave_args(LBS_DEB_SPI, "err %d", err);
> return err;
> }
> @@ -531,7 +532,7 @@ static int if_spi_prog_main_firmware_check_len(struct if_spi_card *card,
> IF_SPI_HIST_CMD_DOWNLOAD_RDY,
> IF_SPI_HIST_CMD_DOWNLOAD_RDY);
> if (err) {
> - lbs_pr_err("timed out waiting for host_int_status\n");
> + pr_err("timed out waiting for host_int_status\n");
> return err;
> }
>
> @@ -541,9 +542,8 @@ static int if_spi_prog_main_firmware_check_len(struct if_spi_card *card,
> return err;
>
> if (len > IF_SPI_CMD_BUF_SIZE) {
> - lbs_pr_err("firmware load device requested a larger "
> - "tranfer than we are prepared to "
> - "handle. (len = %d)\n", len);
> + pr_err("firmware load device requested a larger transfer than we are prepared to handle (len = %d)\n",
> + len);
> return -EIO;
> }
> if (len & 0x1) {
> @@ -572,8 +572,8 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card,
>
> err = spu_wait_for_u16(card, IF_SPI_SCRATCH_1_REG, 0, 0);
> if (err) {
> - lbs_pr_err("%s: timed out waiting for initial "
> - "scratch reg = 0\n", __func__);
> + pr_err("%s: timed out waiting for initial scratch reg = 0\n",
> + __func__);
> goto out;
> }
>
> @@ -589,15 +589,13 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card,
> if (bytes < 0) {
> /* If there are no more bytes left, we would normally
> * expect to have terminated with len = 0 */
> - lbs_pr_err("Firmware load wants more bytes "
> - "than we have to offer.\n");
> + pr_err("Firmware load wants more bytes than we have to offer\n");
> break;
> }
> if (crc_err) {
> /* Previous transfer failed. */
> if (++num_crc_errs > MAX_MAIN_FW_LOAD_CRC_ERR) {
> - lbs_pr_err("Too many CRC errors encountered "
> - "in firmware load.\n");
> + pr_err("Too many CRC errors encountered in firmware load\n");
> err = -EIO;
> goto out;
> }
> @@ -626,21 +624,20 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card,
> prev_len = len;
> }
> if (bytes > prev_len) {
> - lbs_pr_err("firmware load wants fewer bytes than "
> - "we have to offer.\n");
> + pr_err("firmware load wants fewer bytes than we have to offer\n");
> }
>
> /* Confirm firmware download */
> err = spu_wait_for_u32(card, IF_SPI_SCRATCH_4_REG,
> SUCCESSFUL_FW_DOWNLOAD_MAGIC);
> if (err) {
> - lbs_pr_err("failed to confirm the firmware download\n");
> + pr_err("failed to confirm the firmware download\n");
> goto out;
> }
>
> out:
> if (err)
> - lbs_pr_err("failed to load firmware (err=%d)\n", err);
> + pr_err("failed to load firmware (err=%d)\n", err);
> lbs_deb_leave_args(LBS_DEB_SPI, "err %d", err);
> return err;
> }
> @@ -677,14 +674,12 @@ static int if_spi_c2h_cmd(struct if_spi_card *card)
> if (err)
> goto out;
> if (!len) {
> - lbs_pr_err("%s: error: card has no data for host\n",
> - __func__);
> + pr_err("%s: error: card has no data for host\n", __func__);
> err = -EINVAL;
> goto out;
> } else if (len > IF_SPI_CMD_BUF_SIZE) {
> - lbs_pr_err("%s: error: response packet too large: "
> - "%d bytes, but maximum is %d\n",
> - __func__, len, IF_SPI_CMD_BUF_SIZE);
> + pr_err("%s: error: response packet too large: %d bytes, but maximum is %d\n",
> + __func__, len, IF_SPI_CMD_BUF_SIZE);
> err = -EINVAL;
> goto out;
> }
> @@ -705,7 +700,7 @@ static int if_spi_c2h_cmd(struct if_spi_card *card)
>
> out:
> if (err)
> - lbs_pr_err("%s: err=%d\n", __func__, err);
> + pr_err("%s: err=%d\n", __func__, err);
> lbs_deb_leave(LBS_DEB_SPI);
> return err;
> }
> @@ -725,14 +720,12 @@ static int if_spi_c2h_data(struct if_spi_card *card)
> if (err)
> goto out;
> if (!len) {
> - lbs_pr_err("%s: error: card has no data for host\n",
> - __func__);
> + pr_err("%s: error: card has no data for host\n", __func__);
> err = -EINVAL;
> goto out;
> } else if (len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) {
> - lbs_pr_err("%s: error: card has %d bytes of data, but "
> - "our maximum skb size is %zu\n",
> - __func__, len, MRVDRV_ETH_RX_PACKET_BUFFER_SIZE);
> + pr_err("%s: error: card has %d bytes of data, but our maximum skb size is %zu\n",
> + __func__, len, MRVDRV_ETH_RX_PACKET_BUFFER_SIZE);
> err = -EINVAL;
> goto out;
> }
> @@ -763,7 +756,7 @@ free_skb:
> dev_kfree_skb(skb);
> out:
> if (err)
> - lbs_pr_err("%s: err=%d\n", __func__, err);
> + pr_err("%s: err=%d\n", __func__, err);
> lbs_deb_leave(LBS_DEB_SPI);
> return err;
> }
> @@ -785,7 +778,7 @@ static void if_spi_h2c(struct if_spi_card *card,
> port_reg = IF_SPI_CMD_RDWRPORT_REG;
> break;
> default:
> - lbs_pr_err("can't transfer buffer of type %d\n", type);
> + pr_err("can't transfer buffer of type %d\n", type);
> err = -EINVAL;
> goto out;
> }
> @@ -799,7 +792,7 @@ out:
> kfree(packet);
>
> if (err)
> - lbs_pr_err("%s: error %d\n", __func__, err);
> + pr_err("%s: error %d\n", __func__, err);
> }
>
> /* Inform the host about a card event */
> @@ -823,7 +816,7 @@ static void if_spi_e2h(struct if_spi_card *card)
> lbs_queue_event(priv, cause & 0xff);
> out:
> if (err)
> - lbs_pr_err("%s: error %d\n", __func__, err);
> + pr_err("%s: error %d\n", __func__, err);
> }
>
> static void if_spi_host_to_card_worker(struct work_struct *work)
> @@ -843,7 +836,7 @@ static void if_spi_host_to_card_worker(struct work_struct *work)
> err = spu_read_u16(card, IF_SPI_HOST_INT_STATUS_REG,
> &hiStatus);
> if (err) {
> - lbs_pr_err("I/O error\n");
> + pr_err("I/O error\n");
> goto err;
> }
>
> @@ -905,7 +898,7 @@ static void if_spi_host_to_card_worker(struct work_struct *work)
>
> err:
> if (err)
> - lbs_pr_err("%s: got error %d\n", __func__, err);
> + pr_err("%s: got error %d\n", __func__, err);
>
> lbs_deb_leave(LBS_DEB_SPI);
> }
> @@ -927,7 +920,7 @@ static int if_spi_host_to_card(struct lbs_private *priv,
> lbs_deb_enter_args(LBS_DEB_SPI, "type %d, bytes %d", type, nb);
>
> if (nb == 0) {
> - lbs_pr_err("%s: invalid size requested: %d\n", __func__, nb);
> + pr_err("%s: invalid size requested: %d\n", __func__, nb);
> err = -EINVAL;
> goto out;
> }
> @@ -955,7 +948,7 @@ static int if_spi_host_to_card(struct lbs_private *priv,
> spin_unlock_irqrestore(&card->buffer_lock, flags);
> break;
> default:
> - lbs_pr_err("can't transfer buffer of type %d", type);
> + pr_err("can't transfer buffer of type %d\n", type);
> err = -EINVAL;
> break;
> }
> @@ -1016,8 +1009,7 @@ static int if_spi_init_card(struct if_spi_card *card)
> break;
> }
> if (i == ARRAY_SIZE(fw_table)) {
> - lbs_pr_err("Unsupported chip_id: 0x%02x\n",
> - card->card_id);
> + pr_err("Unsupported chip_id: 0x%02x\n", card->card_id);
> err = -ENODEV;
> goto out;
> }
> @@ -1026,7 +1018,7 @@ static int if_spi_init_card(struct if_spi_card *card)
> card->card_id, &fw_table[0], &helper,
> &mainfw);
> if (err) {
> - lbs_pr_err("failed to find firmware (%d)\n", err);
> + pr_err("failed to find firmware (%d)\n", err);
> goto out;
> }
>
> @@ -1149,7 +1141,7 @@ static int __devinit if_spi_probe(struct spi_device *spi)
> err = request_irq(spi->irq, if_spi_host_interrupt,
> IRQF_TRIGGER_FALLING, "libertas_spi", card);
> if (err) {
> - lbs_pr_err("can't get host irq line-- request_irq failed\n");
> + pr_err("can't get host irq line-- request_irq failed\n");
> goto terminate_workqueue;
> }
>
> diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
> index 6524c70..7260791 100644
> --- a/drivers/net/wireless/libertas/if_usb.c
> +++ b/drivers/net/wireless/libertas/if_usb.c
> @@ -1,6 +1,9 @@
> /**
> * This file contains functions used in USB interface module.
> */
> +
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +
> #include <linux/delay.h>
> #include <linux/moduleparam.h>
> #include <linux/firmware.h>
> @@ -145,7 +148,7 @@ static void if_usb_write_bulk_callback(struct urb *urb)
> lbs_host_to_card_done(priv);
> } else {
> /* print the failure status number for debug */
> - lbs_pr_info("URB in failure status: %d\n", urb->status);
> + pr_info("URB in failure status: %d\n", urb->status);
> }
> }
>
> @@ -195,7 +198,7 @@ static void if_usb_setup_firmware(struct lbs_private *priv)
> wake_method.hdr.size = cpu_to_le16(sizeof(wake_method));
> wake_method.action = cpu_to_le16(CMD_ACT_GET);
> if (lbs_cmd_with_response(priv, CMD_802_11_FW_WAKE_METHOD, &wake_method)) {
> - lbs_pr_info("Firmware does not seem to support PS mode\n");
> + pr_info("Firmware does not seem to support PS mode\n");
> priv->fwcapinfo &= ~FW_CAPINFO_PS;
> } else {
> if (le16_to_cpu(wake_method.method) == CMD_WAKE_METHOD_COMMAND_INT) {
> @@ -204,7 +207,7 @@ static void if_usb_setup_firmware(struct lbs_private *priv)
> /* The versions which boot up this way don't seem to
> work even if we set it to the command interrupt */
> priv->fwcapinfo &= ~FW_CAPINFO_PS;
> - lbs_pr_info("Firmware doesn't wake via command interrupt; disabling PS mode\n");
> + pr_info("Firmware doesn't wake via command interrupt; disabling PS mode\n");
> }
> }
> }
> @@ -216,7 +219,7 @@ static void if_usb_fw_timeo(unsigned long priv)
> if (cardp->fwdnldover) {
> lbs_deb_usb("Download complete, no event. Assuming success\n");
> } else {
> - lbs_pr_err("Download timed out\n");
> + pr_err("Download timed out\n");
> cardp->surprise_removed = 1;
> }
> wake_up(&cardp->fw_wq);
> @@ -250,7 +253,7 @@ static int if_usb_probe(struct usb_interface *intf,
>
> cardp = kzalloc(sizeof(struct if_usb_card), GFP_KERNEL);
> if (!cardp) {
> - lbs_pr_err("Out of memory allocating private data.\n");
> + pr_err("Out of memory allocating private data\n");
> goto error;
> }
>
> @@ -340,10 +343,10 @@ static int if_usb_probe(struct usb_interface *intf,
> usb_set_intfdata(intf, cardp);
>
> if (device_create_file(&priv->dev->dev, &dev_attr_lbs_flash_fw))
> - lbs_pr_err("cannot register lbs_flash_fw attribute\n");
> + pr_err("cannot register lbs_flash_fw attribute\n");
>
> if (device_create_file(&priv->dev->dev, &dev_attr_lbs_flash_boot2))
> - lbs_pr_err("cannot register lbs_flash_boot2 attribute\n");
> + pr_err("cannot register lbs_flash_boot2 attribute\n");
>
> /*
> * EHS_REMOVE_WAKEUP is not supported on all versions of the firmware.
> @@ -528,7 +531,7 @@ static int __if_usb_submit_rx_urb(struct if_usb_card *cardp,
> int ret = -1;
>
> if (!(skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE))) {
> - lbs_pr_err("No free skb\n");
> + pr_err("No free skb\n");
> goto rx_ret;
> }
>
> @@ -587,7 +590,7 @@ static void if_usb_receive_fwload(struct urb *urb)
>
> if (tmp[0] == cpu_to_le32(CMD_TYPE_INDICATION) &&
> tmp[1] == cpu_to_le32(MACREG_INT_CODE_FIRMWARE_READY)) {
> - lbs_pr_info("Firmware ready event received\n");
> + pr_info("Firmware ready event received\n");
> wake_up(&cardp->fw_wq);
> } else {
> lbs_deb_usb("Waiting for confirmation; got %x %x\n",
> @@ -614,20 +617,20 @@ static void if_usb_receive_fwload(struct urb *urb)
> bootcmdresp.magic == cpu_to_le32(CMD_TYPE_DATA) ||
> bootcmdresp.magic == cpu_to_le32(CMD_TYPE_INDICATION)) {
> if (!cardp->bootcmdresp)
> - lbs_pr_info("Firmware already seems alive; resetting\n");
> + pr_info("Firmware already seems alive; resetting\n");
> cardp->bootcmdresp = -1;
> } else {
> - lbs_pr_info("boot cmd response wrong magic number (0x%x)\n",
> + pr_info("boot cmd response wrong magic number (0x%x)\n",
> le32_to_cpu(bootcmdresp.magic));
> }
> } else if ((bootcmdresp.cmd != BOOT_CMD_FW_BY_USB) &&
> (bootcmdresp.cmd != BOOT_CMD_UPDATE_FW) &&
> (bootcmdresp.cmd != BOOT_CMD_UPDATE_BOOT2)) {
> - lbs_pr_info("boot cmd response cmd_tag error (%d)\n",
> - bootcmdresp.cmd);
> + pr_info("boot cmd response cmd_tag error (%d)\n",
> + bootcmdresp.cmd);
> } else if (bootcmdresp.result != BOOT_CMD_RESP_OK) {
> - lbs_pr_info("boot cmd response result error (%d)\n",
> - bootcmdresp.result);
> + pr_info("boot cmd response result error (%d)\n",
> + bootcmdresp.result);
> } else {
> cardp->bootcmdresp = 1;
> lbs_deb_usbd(&cardp->udev->dev,
> @@ -892,7 +895,7 @@ static int check_fwfile_format(const uint8_t *data, uint32_t totlen)
> } while (!exit);
>
> if (ret)
> - lbs_pr_err("firmware file format check FAIL\n");
> + pr_err("firmware file format check FAIL\n");
> else
> lbs_deb_fw("firmware file format check PASS\n");
>
> @@ -989,7 +992,7 @@ static int __if_usb_prog_firmware(struct if_usb_card *cardp,
>
> ret = get_fw(cardp, fwname);
> if (ret) {
> - lbs_pr_err("failed to find firmware (%d)\n", ret);
> + pr_err("failed to find firmware (%d)\n", ret);
> goto done;
> }
>
> @@ -1064,13 +1067,13 @@ restart:
> usb_kill_urb(cardp->rx_urb);
>
> if (!cardp->fwdnldover) {
> - lbs_pr_info("failed to load fw, resetting device!\n");
> + pr_info("failed to load fw, resetting device!\n");
> if (--reset_count >= 0) {
> if_usb_reset_device(cardp);
> goto restart;
> }
>
> - lbs_pr_info("FW download failure, time = %d ms\n", i * 100);
> + pr_info("FW download failure, time = %d ms\n", i * 100);
> ret = -EIO;
> goto release_fw;
> }
> diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
> index ca8149c..639461b 100644
> --- a/drivers/net/wireless/libertas/main.c
> +++ b/drivers/net/wireless/libertas/main.c
> @@ -4,6 +4,8 @@
> * thread etc..
> */
>
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +
> #include <linux/moduleparam.h>
> #include <linux/delay.h>
> #include <linux/etherdevice.h>
> @@ -153,7 +155,7 @@ static void lbs_tx_timeout(struct net_device *dev)
>
> lbs_deb_enter(LBS_DEB_TX);
>
> - lbs_pr_err("tx watch dog timeout\n");
> + pr_err("tx watch dog timeout\n");
>
> dev->trans_start = jiffies; /* prevent tx timeout */
>
> @@ -462,7 +464,7 @@ static int lbs_thread(void *data)
> if (priv->cmd_timed_out && priv->cur_cmd) {
> struct cmd_ctrl_node *cmdnode = priv->cur_cmd;
>
> - lbs_pr_info("Timeout submitting command 0x%04x\n",
> + pr_info("Timeout submitting command 0x%04x\n",
> le16_to_cpu(cmdnode->cmdbuf->command));
> lbs_complete_command(priv, cmdnode, -ETIMEDOUT);
> if (priv->reset_card)
> @@ -490,8 +492,7 @@ static int lbs_thread(void *data)
> * after firmware fixes it
> */
> priv->psstate = PS_STATE_AWAKE;
> - lbs_pr_alert("ignore PS_SleepConfirm in "
> - "non-connected state\n");
> + pr_alert("ignore PS_SleepConfirm in non-connected state\n");
> }
> }
>
> @@ -585,7 +586,7 @@ int lbs_suspend(struct lbs_private *priv)
> if (priv->is_deep_sleep) {
> ret = lbs_set_deep_sleep(priv, 0);
> if (ret) {
> - lbs_pr_err("deep sleep cancellation failed: %d\n", ret);
> + pr_err("deep sleep cancellation failed: %d\n", ret);
> return ret;
> }
> priv->deep_sleep_required = 1;
> @@ -618,7 +619,7 @@ int lbs_resume(struct lbs_private *priv)
> priv->deep_sleep_required = 0;
> ret = lbs_set_deep_sleep(priv, 1);
> if (ret)
> - lbs_pr_err("deep sleep activation failed: %d\n", ret);
> + pr_err("deep sleep activation failed: %d\n", ret);
> }
>
> if (priv->setup_fw_on_resume)
> @@ -644,7 +645,7 @@ static void lbs_cmd_timeout_handler(unsigned long data)
> if (!priv->cur_cmd)
> goto out;
>
> - lbs_pr_info("command 0x%04x timed out\n",
> + pr_info("command 0x%04x timed out\n",
> le16_to_cpu(priv->cur_cmd->cmdbuf->command));
>
> priv->cmd_timed_out = 1;
> @@ -748,7 +749,7 @@ static int lbs_init_adapter(struct lbs_private *priv)
>
> /* Allocate the command buffers */
> if (lbs_allocate_cmd_buffer(priv)) {
> - lbs_pr_err("Out of memory allocating command buffers\n");
> + pr_err("Out of memory allocating command buffers\n");
> ret = -ENOMEM;
> goto out;
> }
> @@ -758,7 +759,7 @@ static int lbs_init_adapter(struct lbs_private *priv)
> /* Create the event FIFO */
> ret = kfifo_alloc(&priv->event_fifo, sizeof(u32) * 16, GFP_KERNEL);
> if (ret) {
> - lbs_pr_err("Out of memory allocating event FIFO buffer\n");
> + pr_err("Out of memory allocating event FIFO buffer\n");
> goto out;
> }
>
> @@ -809,7 +810,7 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
> /* Allocate an Ethernet device and register it */
> wdev = lbs_cfg_alloc(dmdev);
> if (IS_ERR(wdev)) {
> - lbs_pr_err("cfg80211 init failed\n");
> + pr_err("cfg80211 init failed\n");
> goto done;
> }
>
> @@ -818,7 +819,7 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
> priv->wdev = wdev;
>
> if (lbs_init_adapter(priv)) {
> - lbs_pr_err("failed to initialize adapter structure.\n");
> + pr_err("failed to initialize adapter structure\n");
> goto err_wdev;
> }
>
> @@ -950,7 +951,7 @@ int lbs_start_card(struct lbs_private *priv)
> goto done;
>
> if (lbs_cfg_register(priv)) {
> - lbs_pr_err("cannot register device\n");
> + pr_err("cannot register device\n");
> goto done;
> }
>
> @@ -960,7 +961,7 @@ int lbs_start_card(struct lbs_private *priv)
>
> lbs_debugfs_init_one(priv, dev);
>
> - lbs_pr_info("%s: Marvell WLAN 802.11 adapter\n", dev->name);
> + pr_info("%s: Marvell WLAN 802.11 adapter\n", dev->name);
>
> ret = 0;
>
> @@ -1087,16 +1088,14 @@ int lbs_get_firmware(struct device *dev, const char *user_helper,
> if (user_helper) {
> ret = request_firmware(helper, user_helper, dev);
> if (ret) {
> - lbs_pr_err("couldn't find helper firmware %s",
> - user_helper);
> + pr_err("couldn't find helper firmware %s", user_helper);
> goto fail;
> }
> }
> if (user_mainfw) {
> ret = request_firmware(mainfw, user_mainfw, dev);
> if (ret) {
> - lbs_pr_err("couldn't find main firmware %s",
> - user_mainfw);
> + pr_err("couldn't find main firmware %s", user_mainfw);
> goto fail;
> }
> }
> diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c
> index 9d097b9..f7c51cb 100644
> --- a/drivers/net/wireless/libertas/mesh.c
> +++ b/drivers/net/wireless/libertas/mesh.c
> @@ -1,3 +1,5 @@
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +
> #include <linux/delay.h>
> #include <linux/etherdevice.h>
> #include <linux/netdevice.h>
> @@ -246,7 +248,7 @@ int lbs_init_mesh(struct lbs_private *priv)
> lbs_add_mesh(priv);
>
> if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
> - lbs_pr_err("cannot register lbs_mesh attribute\n");
> + pr_err("cannot register lbs_mesh attribute\n");
>
> ret = 1;
> }
> @@ -374,7 +376,7 @@ int lbs_add_mesh(struct lbs_private *priv)
> /* Register virtual mesh interface */
> ret = register_netdev(mesh_dev);
> if (ret) {
> - lbs_pr_err("cannot register mshX virtual interface\n");
> + pr_err("cannot register mshX virtual interface\n");
> goto err_free;
> }
>
> @@ -926,7 +928,7 @@ static ssize_t mesh_id_get(struct device *dev, struct device_attribute *attr,
> return ret;
>
> if (defs.meshie.val.mesh_id_len > IEEE80211_MAX_SSID_LEN) {
> - lbs_pr_err("inconsistent mesh ID length");
> + pr_err("inconsistent mesh ID length\n");
> defs.meshie.val.mesh_id_len = IEEE80211_MAX_SSID_LEN;
> }
>
> diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c
> index a2b1df2..fd045aa 100644
> --- a/drivers/net/wireless/libertas/rx.c
> +++ b/drivers/net/wireless/libertas/rx.c
> @@ -1,6 +1,9 @@
> /**
> * This file contains the handling of RX in wlan driver.
> */
> +
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +
> #include <linux/etherdevice.h>
> #include <linux/slab.h>
> #include <linux/types.h>
> @@ -191,7 +194,7 @@ static u8 convert_mv_rate_to_radiotap(u8 rate)
> case 12: /* 54 Mbps */
> return 108;
> }
> - lbs_pr_alert("Invalid Marvell WLAN rate %i\n", rate);
> + pr_alert("Invalid Marvell WLAN rate %i\n", rate);
> return 0;
> }
>
> @@ -248,7 +251,7 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
> /* add space for the new radio header */
> if ((skb_headroom(skb) < sizeof(struct rx_radiotap_hdr)) &&
> pskb_expand_head(skb, sizeof(struct rx_radiotap_hdr), 0, GFP_ATOMIC)) {
> - lbs_pr_alert("%s: couldn't pskb_expand_head\n", __func__);
> + pr_alert("%s: couldn't pskb_expand_head\n", __func__);
> ret = -ENOMEM;
> kfree_skb(skb);
> goto done;
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: Divide error in bictcp_cong_avoid ?
From: David Miller @ 2011-05-04 19:40 UTC (permalink / raw)
To: shemminger; +Cc: Valdis.Kletnieks, rdunlap, lkml, netdev, linux-kernel
In-Reply-To: <20110504123738.7bb4d1ee@nehalam>
From: Stephen Hemminger <shemminger@vyatta.com>
Date: Wed, 4 May 2011 12:37:38 -0700
> Don't use BIC, it is known to be unfair between flows.
That doesn't fix the user's bug, nothing in the kernel should causes
crashes under normal circumstances.
Please stop with this deflecting on this report and instead try to
figure out why the illegal divide happens.
Thanks.
^ permalink raw reply
* Re: [PATCH 2/4] [RFC] virtio: Introduce new API to get free space
From: Michael S. Tsirkin @ 2011-05-04 19:58 UTC (permalink / raw)
To: Krishna Kumar; +Cc: davem, eric.dumazet, kvm, netdev, rusty, mashirle
In-Reply-To: <20110504140319.14817.23145.sendpatchset@krkumar2.in.ibm.com>
On Wed, May 04, 2011 at 07:33:19PM +0530, Krishna Kumar wrote:
> @@ -185,11 +193,6 @@ int virtqueue_add_buf_gfp(struct virtque
> if (vq->num_free < out + in) {
> pr_debug("Can't add buf len %i - avail = %i\n",
> out + in, vq->num_free);
> - /* FIXME: for historical reasons, we force a notify here if
> - * there are outgoing parts to the buffer. Presumably the
> - * host should service the ring ASAP. */
> - if (out)
> - vq->notify(&vq->vq);
> END_USE(vq);
> return -ENOSPC;
> }
I thought about it some more. We should typically not get into this
state with the current driver as we check capacity upfront.
So why would this change help performance?
Shirley, any idea?
--
MST
^ permalink raw reply
* Re: [PATCH 2/4] [RFC] virtio: Introduce new API to get free space
From: Michael S. Tsirkin @ 2011-05-04 20:00 UTC (permalink / raw)
To: Krishna Kumar; +Cc: davem, eric.dumazet, kvm, netdev, rusty
In-Reply-To: <20110504145019.GB15823@redhat.com>
On Wed, May 04, 2011 at 05:50:19PM +0300, Michael S. Tsirkin wrote:
> > @@ -185,11 +193,6 @@ int virtqueue_add_buf_gfp(struct virtque
> > if (vq->num_free < out + in) {
> > pr_debug("Can't add buf len %i - avail = %i\n",
> > out + in, vq->num_free);
> > - /* FIXME: for historical reasons, we force a notify here if
> > - * there are outgoing parts to the buffer. Presumably the
> > - * host should service the ring ASAP. */
> > - if (out)
> > - vq->notify(&vq->vq);
> > END_USE(vq);
> > return -ENOSPC;
> > }
>
> This will break qemu versions 0.13 and back.
> I'm adding some new virtio ring flags, we'll be
> able to reuse one of these to mean 'no need for
> work around', I think.
Not really, it wont. We shall almost never get here at all.
But then, why would this help performance?
> --
> MST
^ permalink raw reply
* Re: Divide error in bictcp_cong_avoid ?
From: Valdis.Kletnieks @ 2011-05-04 20:01 UTC (permalink / raw)
To: David Miller; +Cc: shemminger, rdunlap, lkml, netdev, linux-kernel
In-Reply-To: <20110504.124053.260068550.davem@davemloft.net>
[-- Attachment #1: Type: text/plain, Size: 532 bytes --]
On Wed, 04 May 2011 12:40:53 PDT, David Miller said:
> From: Stephen Hemminger <shemminger@vyatta.com>
> Date: Wed, 4 May 2011 12:37:38 -0700
>
> > Don't use BIC, it is known to be unfair between flows.
>
> That doesn't fix the user's bug, nothing in the kernel should causes
> crashes under normal circumstances.
And if it's a "don't use" thing, maybe it's time to deprecate it and/or
otherwise discourage its use? I know *my* config still has it mostly because it
*seems* to work, and nothing's suggested I should change it.
[-- Attachment #2: Type: application/pgp-signature, Size: 227 bytes --]
^ permalink raw reply
* Re: 2.6.38.2, kernel panic, probably related to framentation handling
From: Eric Dumazet @ 2011-05-04 20:02 UTC (permalink / raw)
To: Denys Fedoryshchenko, David Miller; +Cc: netdev
In-Reply-To: <1304532674.32152.16.camel@edumazet-laptop>
Le mercredi 04 mai 2011 à 20:11 +0200, Eric Dumazet a écrit :
> Le mercredi 04 mai 2011 à 19:03 +0200, Eric Dumazet a écrit :
>
> > Hi Denys
> >
> > Is it reproductible, and possibly on latest kernel ?
> >
> > We fixed some bugs lately (assuming you also use a bridge ?)
> >
> > Could you send the disassembled code on your kernel of icmp_send() ?
>
> Oh well, I think I found the problem, I am working on a patch and send
> it shortly.
>
> Thanks
>
I believe bug is one year old (2.6.35), please try following patch.
Thanks !
[PATCH] net: ip_expire() must revalidate route
Commit 4a94445c9a5c (net: Use ip_route_input_noref() in input path)
added a bug in IP defragmentation handling, in case timeout is fired.
When a frame is defragmented, we use last skb dst field when building
final skb. Its dst is valid, since we are in rcu read section.
But if a timeout occurs, we take first queued fragment to build one ICMP
TIME EXCEEDED message. Problem is all queued skb have weak dst pointers,
since we escaped RCU critical section after their queueing. icmp_send()
might dereference a now freed (and possibly reused) part of memory.
Calling skb_dst_drop() and ip_route_input_noref() to revalidate route is
the only possible choice.
Reported-by: Denys Fedoryshchenko <denys@visp.net.lb>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
net/ipv4/ip_fragment.c | 31 +++++++++++++++----------------
1 file changed, 15 insertions(+), 16 deletions(-)
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index a1151b8..b1d282f 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -223,31 +223,30 @@ static void ip_expire(unsigned long arg)
if ((qp->q.last_in & INET_FRAG_FIRST_IN) && qp->q.fragments != NULL) {
struct sk_buff *head = qp->q.fragments;
+ const struct iphdr *iph;
+ int err;
rcu_read_lock();
head->dev = dev_get_by_index_rcu(net, qp->iif);
if (!head->dev)
goto out_rcu_unlock;
+ /* skb dst is stale, drop it, and perform route lookup again */
+ skb_dst_drop(head);
+ iph = ip_hdr(head);
+ err = ip_route_input_noref(head, iph->daddr, iph->saddr,
+ iph->tos, head->dev);
+ if (err)
+ goto out_rcu_unlock;
+
/*
- * Only search router table for the head fragment,
- * when defraging timeout at PRE_ROUTING HOOK.
+ * Only an end host needs to send an ICMP
+ * "Fragment Reassembly Timeout" message, per RFC792.
*/
- if (qp->user == IP_DEFRAG_CONNTRACK_IN && !skb_dst(head)) {
- const struct iphdr *iph = ip_hdr(head);
- int err = ip_route_input(head, iph->daddr, iph->saddr,
- iph->tos, head->dev);
- if (unlikely(err))
- goto out_rcu_unlock;
-
- /*
- * Only an end host needs to send an ICMP
- * "Fragment Reassembly Timeout" message, per RFC792.
- */
- if (skb_rtable(head)->rt_type != RTN_LOCAL)
- goto out_rcu_unlock;
+ if (qp->user == IP_DEFRAG_CONNTRACK_IN &&
+ skb_rtable(head)->rt_type != RTN_LOCAL)
+ goto out_rcu_unlock;
- }
/* Send an ICMP "Fragment Reassembly Timeout" message. */
icmp_send(head, ICMP_TIME_EXCEEDED, ICMP_EXC_FRAGTIME, 0);
^ permalink raw reply related
* [PATCH] tcp_cubic: limit delayed_ack ratio to prevent divide error
From: Stephen Hemminger @ 2011-05-04 20:04 UTC (permalink / raw)
To: David Miller, Sangtae Ha, Injong Rhee
Cc: Valdis.Kletnieks, rdunlap, lkml, netdev, linux-kernel
In-Reply-To: <20110504.124053.260068550.davem@davemloft.net>
TCP Cubic keeps a metric that estimates the amount of delayed
acknowledgements to use in adjusting the window. If an abnormally
large number of packets are acknowledged at once, then the update
could wrap and reach zero. This kind of ACK could only
happen when there was a large window and huge number of
ACK's were lost.
This patch limits the value of delayed ack ratio. The choice of 32
is just a conservative value since normally it should be range of
1 to 4 packets.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
---
Patch against 2.6.39-rc5+
--- a/net/ipv4/tcp_cubic.c 2011-05-04 11:58:49.666027155 -0700
+++ b/net/ipv4/tcp_cubic.c 2011-05-04 12:52:34.716767304 -0700
@@ -93,6 +93,7 @@ struct bictcp {
u32 ack_cnt; /* number of acks */
u32 tcp_cwnd; /* estimated tcp cwnd */
#define ACK_RATIO_SHIFT 4
+#define ACK_RATIO_LIMIT (32u << ACK_RATIO_SHIFT)
u16 delayed_ack; /* estimate the ratio of Packets/ACKs << 4 */
u8 sample_cnt; /* number of samples to decide curr_rtt */
u8 found; /* the exit point is found? */
@@ -398,8 +399,12 @@ static void bictcp_acked(struct sock *sk
u32 delay;
if (icsk->icsk_ca_state == TCP_CA_Open) {
- cnt -= ca->delayed_ack >> ACK_RATIO_SHIFT;
- ca->delayed_ack += cnt;
+ u32 ratio = ca->delayed_ack;
+
+ ratio -= ca->delayed_ack >> ACK_RATIO_SHIFT;
+ ratio += cnt;
+
+ ca->delayed_ack = min(ratio, ACK_RATIO_LIMIT);
}
/* Some calls are for duplicates without timetamps */
^ permalink raw reply
* Re: ath5k regression associating with APs in 2.6.38
From: Nick Kossifidis @ 2011-05-04 20:09 UTC (permalink / raw)
To: John W. Linville, Jiri Slaby, Nick Kossifidis, Luis R. Rodriguez,
Bob Copeland
In-Reply-To: <20110504192639.GB4551@thinkpad-t410>
2011/5/4 Seth Forshee <seth.forshee@canonical.com>:
> On Wed, May 04, 2011 at 01:27:17PM -0400, John W. Linville wrote:
>> On Wed, May 04, 2011 at 10:38:19AM -0500, Seth Forshee wrote:
>> > I've been investigating some reports of a regression in associating with
>> > APs with AR2413 in 2.6.38. Association repeatedly fails with some
>> > "direct probe to x timed out" messages (see syslog excerpt below),
>> > although it will generally associate eventually, after many tries.
>> >
>> > Bisection identifies 8aec7af (ath5k: Support synth-only channel change
>> > for AR2413/AR5413) as offending commit. Prior to this commit there are
>> > no direct probe messages at all in the logs. I've also found that
>> > forcing fast to false at the top of ath5k_hw_reset() fixes the issue.
>> > I'm not sure what the connection is between this commit and the
>> > timeouts. Any suggestions?
>>
>> Have you tried reverting that commit on top of 2.6.38? Can you
>> recreate the issue with 2.6.39-rc6 (or later)?
>
> I started to revert that commit, but it wasn't straight-forward due to
> later changes. Forcing fast to false in ath5k_hw_reset() acts as a
> functional revert of sorts since that should force it back to a full
> reset for all channel changes, and it's much simpler than working out
> the right way to revert the commit. I think the results suggest strongly
> that a revert is likely to fix the problem. I can finish the work to
> revert if you'd still like to see the results.
>
> Testing a previous .39-rc kernel still exhibited the failure. I don't
> recall which one it was and apparently forgot to make note of it. I'll
> request testing against rc6.
>
> Thanks,
> Seth
>
Do you get scan results ?
Can you enable ATH5K_DEBUG_RESET and see what you get ?
--
GPG ID: 0xD21DB2DB
As you read this post global entropy rises. Have Fun ;-)
Nick
^ permalink raw reply
* [PATCH 0/5] More rt->rt_{src,dst} removals.
From: David Miller @ 2011-05-04 20:19 UTC (permalink / raw)
To: netdev
After this set the number of uses of rt->rt_{src,dst} are very small.
One case to hit still will need a slight rearrangement of how we do
SRR handling, since SRR handling on input pops the nexthop and thus
creates situations where iph->daddr != rt->rt_dst and thus eliminates
the posibility of converting the rt->rt_dst access in ip_forward().
Another class of remaining cases occur in situations where we can
fetch the saddr/daddr from the inet socket.
Soon, all that will be left are the assignments and netlink dump code
cases in net/ipv4/route.c
^ permalink raw reply
* [PATCH 1/5] ipv4: Use flowi4->{daddr,saddr} in ipip_tunnel_xmit().
From: David Miller @ 2011-05-04 20:19 UTC (permalink / raw)
To: netdev
Instead of rt->rt_{dst,src}
Signed-off-by: David S. Miller <davem@davemloft.net>
---
net/ipv4/ipip.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 88d96bd..bfa0b98 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -550,8 +550,8 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
iph->frag_off = df;
iph->protocol = IPPROTO_IPIP;
iph->tos = INET_ECN_encapsulate(tos, old_iph->tos);
- iph->daddr = rt->rt_dst;
- iph->saddr = rt->rt_src;
+ iph->daddr = fl4.daddr;
+ iph->saddr = fl4.saddr;
if ((iph->ttl = tiph->ttl) == 0)
iph->ttl = old_iph->ttl;
--
1.7.4.5
^ permalink raw reply related
* [PATCH 2/5] ipv4: In ip_build_and_send_pkt() use 'saddr' and 'daddr' args passed in.
From: David Miller @ 2011-05-04 20:19 UTC (permalink / raw)
To: netdev
Instead of rt->rt_{dst,src}
The only tricky part is source route option handling.
If the source route option is enabled we can't just use plain 'daddr',
we have to use opt->opt.faddr.
Signed-off-by: David S. Miller <davem@davemloft.net>
---
net/ipv4/ip_output.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 3aa4c31..db38c18 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -158,8 +158,8 @@ int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk,
else
iph->frag_off = 0;
iph->ttl = ip_select_ttl(inet, &rt->dst);
- iph->daddr = rt->rt_dst;
- iph->saddr = rt->rt_src;
+ iph->daddr = (opt && opt->opt.srr ? opt->opt.faddr : daddr);
+ iph->saddr = saddr;
iph->protocol = sk->sk_protocol;
ip_select_ident(iph, &rt->dst, sk);
--
1.7.4.5
^ permalink raw reply related
* [PATCH 3/5] ipv4: Pass explicit saddr/daddr args to ipmr_get_route().
From: David Miller @ 2011-05-04 20:19 UTC (permalink / raw)
To: netdev
This eliminates the need to use rt->rt_{src,dst}.
Signed-off-by: David S. Miller <davem@davemloft.net>
---
include/linux/mroute.h | 1 +
net/ipv4/ipmr.c | 16 ++++++++--------
net/ipv4/route.c | 4 +++-
3 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/include/linux/mroute.h b/include/linux/mroute.h
index b21d567..46caaf4 100644
--- a/include/linux/mroute.h
+++ b/include/linux/mroute.h
@@ -244,6 +244,7 @@ struct mfc_cache {
#ifdef __KERNEL__
struct rtmsg;
extern int ipmr_get_route(struct net *net, struct sk_buff *skb,
+ __be32 saddr, __be32 daddr,
struct rtmsg *rtm, int nowait);
#endif
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 86033b7..30a7763 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -2041,20 +2041,20 @@ rtattr_failure:
return -EMSGSIZE;
}
-int ipmr_get_route(struct net *net,
- struct sk_buff *skb, struct rtmsg *rtm, int nowait)
+int ipmr_get_route(struct net *net, struct sk_buff *skb,
+ __be32 saddr, __be32 daddr,
+ struct rtmsg *rtm, int nowait)
{
- int err;
- struct mr_table *mrt;
struct mfc_cache *cache;
- struct rtable *rt = skb_rtable(skb);
+ struct mr_table *mrt;
+ int err;
mrt = ipmr_get_table(net, RT_TABLE_DEFAULT);
if (mrt == NULL)
return -ENOENT;
rcu_read_lock();
- cache = ipmr_cache_find(mrt, rt->rt_src, rt->rt_dst);
+ cache = ipmr_cache_find(mrt, saddr, daddr);
if (cache == NULL) {
struct sk_buff *skb2;
@@ -2087,8 +2087,8 @@ int ipmr_get_route(struct net *net,
skb_reset_network_header(skb2);
iph = ip_hdr(skb2);
iph->ihl = sizeof(struct iphdr) >> 2;
- iph->saddr = rt->rt_src;
- iph->daddr = rt->rt_dst;
+ iph->saddr = saddr;
+ iph->daddr = daddr;
iph->version = 0;
err = ipmr_cache_unresolved(mrt, vif, skb2);
read_unlock(&mrt_lock);
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 3bc6854..6a83840 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -2857,7 +2857,9 @@ static int rt_fill_info(struct net *net,
if (ipv4_is_multicast(dst) && !ipv4_is_local_multicast(dst) &&
IPV4_DEVCONF_ALL(net, MC_FORWARDING)) {
- int err = ipmr_get_route(net, skb, r, nowait);
+ int err = ipmr_get_route(net, skb,
+ rt->rt_src, rt->rt_dst,
+ r, nowait);
if (err <= 0) {
if (!nowait) {
if (err == 0)
--
1.7.4.5
^ permalink raw reply related
* [PATCH 4/5] ipv4: Kill rt->rt_{src, dst} usage in IP GRE tunnels.
From: David Miller @ 2011-05-04 20:19 UTC (permalink / raw)
To: netdev
First, make callers pass on-stack flowi4 to ip_route_output_gre()
so they can get at the fully resolved flow key.
Next, use that in ipgre_tunnel_xmit() to avoid the need to use
rt->rt_{dst,src}.
Signed-off-by: David S. Miller <davem@davemloft.net>
---
include/net/route.h | 19 +++++++++----------
net/ipv4/ip_gre.c | 37 +++++++++++++++++++++----------------
2 files changed, 30 insertions(+), 26 deletions(-)
diff --git a/include/net/route.h b/include/net/route.h
index 8c02c87..9f8070b 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -152,19 +152,18 @@ static inline struct rtable *ip_route_output_ports(struct net *net, struct flowi
return ip_route_output_flow(net, fl4, sk);
}
-static inline struct rtable *ip_route_output_gre(struct net *net,
+static inline struct rtable *ip_route_output_gre(struct net *net, struct flowi4 *fl4,
__be32 daddr, __be32 saddr,
__be32 gre_key, __u8 tos, int oif)
{
- struct flowi4 fl4 = {
- .flowi4_oif = oif,
- .daddr = daddr,
- .saddr = saddr,
- .flowi4_tos = tos,
- .flowi4_proto = IPPROTO_GRE,
- .fl4_gre_key = gre_key,
- };
- return ip_route_output_key(net, &fl4);
+ memset(fl4, 0, sizeof(*fl4));
+ fl4->flowi4_oif = oif;
+ fl4->daddr = daddr;
+ fl4->saddr = saddr;
+ fl4->flowi4_tos = tos;
+ fl4->flowi4_proto = IPPROTO_GRE;
+ fl4->fl4_gre_key = gre_key;
+ return ip_route_output_key(net, fl4);
}
extern int ip_route_input_common(struct sk_buff *skb, __be32 dst, __be32 src,
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 24efd35..10e9b5a 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -699,6 +699,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
struct pcpu_tstats *tstats;
const struct iphdr *old_iph = ip_hdr(skb);
const struct iphdr *tiph;
+ struct flowi4 fl4;
u8 tos;
__be16 df;
struct rtable *rt; /* Route to the other host */
@@ -769,7 +770,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
tos = ipv6_get_dsfield((const struct ipv6hdr *)old_iph);
}
- rt = ip_route_output_gre(dev_net(dev), dst, tiph->saddr,
+ rt = ip_route_output_gre(dev_net(dev), &fl4, dst, tiph->saddr,
tunnel->parms.o_key, RT_TOS(tos),
tunnel->parms.link);
if (IS_ERR(rt)) {
@@ -873,8 +874,8 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
iph->frag_off = df;
iph->protocol = IPPROTO_GRE;
iph->tos = ipgre_ecn_encapsulate(tos, old_iph, skb);
- iph->daddr = rt->rt_dst;
- iph->saddr = rt->rt_src;
+ iph->daddr = fl4.daddr;
+ iph->saddr = fl4.saddr;
if ((iph->ttl = tiph->ttl) == 0) {
if (skb->protocol == htons(ETH_P_IP))
@@ -938,12 +939,14 @@ static int ipgre_tunnel_bind_dev(struct net_device *dev)
/* Guess output device to choose reasonable mtu and needed_headroom */
if (iph->daddr) {
- struct rtable *rt = ip_route_output_gre(dev_net(dev),
- iph->daddr, iph->saddr,
- tunnel->parms.o_key,
- RT_TOS(iph->tos),
- tunnel->parms.link);
-
+ struct flowi4 fl4;
+ struct rtable *rt;
+
+ rt = ip_route_output_gre(dev_net(dev), &fl4,
+ iph->daddr, iph->saddr,
+ tunnel->parms.o_key,
+ RT_TOS(iph->tos),
+ tunnel->parms.link);
if (!IS_ERR(rt)) {
tdev = rt->dst.dev;
ip_rt_put(rt);
@@ -1196,13 +1199,15 @@ static int ipgre_open(struct net_device *dev)
struct ip_tunnel *t = netdev_priv(dev);
if (ipv4_is_multicast(t->parms.iph.daddr)) {
- struct rtable *rt = ip_route_output_gre(dev_net(dev),
- t->parms.iph.daddr,
- t->parms.iph.saddr,
- t->parms.o_key,
- RT_TOS(t->parms.iph.tos),
- t->parms.link);
-
+ struct flowi4 fl4;
+ struct rtable *rt;
+
+ rt = ip_route_output_gre(dev_net(dev), &fl4,
+ t->parms.iph.daddr,
+ t->parms.iph.saddr,
+ t->parms.o_key,
+ RT_TOS(t->parms.iph.tos),
+ t->parms.link);
if (IS_ERR(rt))
return -EADDRNOTAVAIL;
dev = rt->dst.dev;
--
1.7.4.5
^ permalink raw reply related
* [PATCH 5/5] ipv6: Use flowi4->{daddr,saddr} in ipip6_tunnel_xmit().
From: David Miller @ 2011-05-04 20:19 UTC (permalink / raw)
To: netdev
Instead of rt->rt_{dst,src}
Signed-off-by: David S. Miller <davem@davemloft.net>
---
net/ipv6/sit.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index a24fb14..c53abcf 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -828,8 +828,8 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
iph->frag_off = df;
iph->protocol = IPPROTO_IPV6;
iph->tos = INET_ECN_encapsulate(tos, ipv6_get_dsfield(iph6));
- iph->daddr = rt->rt_dst;
- iph->saddr = rt->rt_src;
+ iph->daddr = fl4.daddr;
+ iph->saddr = fl4.saddr;
if ((iph->ttl = tiph->ttl) == 0)
iph->ttl = iph6->hop_limit;
--
1.7.4.5
^ permalink raw reply related
* [PATCHv2] virtio-spec: 64 bit features, used/avail event
From: Michael S. Tsirkin @ 2011-05-04 20:32 UTC (permalink / raw)
To: linux-kernel
Cc: Rusty Russell, Carsten Otte, Christian Borntraeger, linux390,
Martin Schwidefsky, Heiko Carstens, Shirley Ma, lguest,
virtualization, netdev, linux-s390, kvm, Krishna Kumar,
Tom Lendacky, steved, habanero
I'm working on a patchset (to follow shortly)
that modified the notificatin hand-off in virtio to be basically
like Xen: each side published an index, the other side only triggers
an event when it crosses that index value
(Xen event indexes start at 1, ours start at 0 for
backward-compatiblity, but that's minor).
Especially for testing, it is very convenient to have
separate feature bits for this change in used and available
ring; since we've run out of bits in the 32 bit field,
I added another 32 bit and bit 31 enables that.
I started with using both flags and indexes in parallel,
but switched to doing either-or: this means we do
not need to tweak memory access ordering as index access just
replaces flags access.
A note on naming: the index replacing avail->flags is named
used_event, the index replacing used->flags is named
avail_event to stress the fact that these actually
point into the other side of the ring:
event is triggered when avail->idx == used->avail_event + 1
and when used->idx == avail->used_event + 1, respectively.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
Changes from v1:
- minor wording changes to address comments
- fill a couple of places I missed
- add text about access ordering
virtio-spec.lyx | 719 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 700 insertions(+), 19 deletions(-)
diff --git a/virtio-spec.lyx b/virtio-spec.lyx
index f7c9c38..95fd926 100644
--- a/virtio-spec.lyx
+++ b/virtio-spec.lyx
@@ -1,4 +1,4 @@
-#LyX 1.6.7 created this file. For more info see http://www.lyx.org/
+#LyX 1.6.8 created this file. For more info see http://www.lyx.org/
\lyxformat 345
\begin_document
\begin_header
@@ -36,7 +36,7 @@
\paperpagestyle default
\tracking_changes true
\output_changes true
-\author ""
+\author "Michael S. Tsirkin"
\author ""
\end_header
@@ -953,6 +953,10 @@ ISR
\size footnotesize
Features
+\change_inserted 0 1304329091
+ bits 0:31
+\change_unchanged
+
\end_layout
\end_inset
@@ -964,6 +968,10 @@ Features
\size footnotesize
Features
+\change_inserted 0 1304329086
+ bits 0:31
+\change_unchanged
+
\end_layout
\end_inset
@@ -1186,6 +1194,177 @@ Vector
\end_layout
\begin_layout Standard
+
+\change_inserted 0 1304328924
+Finally, if feature bits (VIRTIO_F_FEATURES_HI) this is immediately followed
+ by two additional fields:
+\end_layout
+
+\begin_layout Standard
+
+\change_inserted 0 1304328925
+\begin_inset Tabular
+<lyxtabular version="3" rows="4" columns="3">
+<features>
+<column alignment="left" valignment="top" width="0">
+<column alignment="left" valignment="top" width="0">
+<column alignment="left" valignment="top" width="0">
+<row>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\change_inserted 0 1304328925
+Bits
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\change_inserted 0 1304328925
+32
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\change_inserted 0 1304328925
+32
+\end_layout
+
+\end_inset
+</cell>
+</row>
+<row>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\change_inserted 0 1304328925
+Read/Write
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\change_inserted 0 1304328925
+R
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\change_inserted 0 1304328925
+R+W
+\end_layout
+
+\end_inset
+</cell>
+</row>
+<row>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\change_inserted 0 1304328925
+Purpose
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\change_inserted 0 1304328925
+
+\size footnotesize
+Device
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\change_inserted 0 1304328925
+
+\size footnotesize
+Guest
+\end_layout
+
+\end_inset
+</cell>
+</row>
+<row>
+<cell alignment="center" valignment="top" bottomline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\change_inserted 0 1304328925
+
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" bottomline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\change_inserted 0 1304329099
+
+\size footnotesize
+Features bits 32:63
+\end_layout
+
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" bottomline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\begin_layout Plain Layout
+
+\change_inserted 0 1304329102
+
+\size footnotesize
+Features bits 32:63
+\end_layout
+
+\end_inset
+</cell>
+</row>
+</lyxtabular>
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
Immediately following these general headers, there may be device-specific
headers:
\end_layout
@@ -1348,7 +1527,20 @@ Feature Bits
The least significant 31 bits of the first configuration field indicates
the features that the device supports (the high bit is reserved, and will
be used to indicate the presence of future feature bits elsewhere).
- The bits are allocated as follows:
+
+\change_inserted 0 1304331636
+If more than 31 feature bits are supported, the device indicates so by setting
+ feature bit 31 (see
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "cha:Reserved-Feature-Bits"
+
+\end_inset
+
+).
+
+\change_unchanged
+The bits are allocated as follows:
\end_layout
\begin_layout Description
@@ -1372,7 +1564,33 @@ to
\begin_inset space ~
\end_inset
-30 Feature bits reserved for extensions to the queue mechanism
+
+\change_inserted 0 1304329326
+4
+\change_deleted 0 1304329325
+3
+\change_unchanged
+0 Feature bits reserved for extensions to the queue
+\change_inserted 0 1304540448
+and feature negotiation
+\change_unchanged
+mechanism
+\change_inserted 0 1304540449
+s
+\end_layout
+
+\begin_layout Description
+
+\change_inserted 0 1304329398
+41
+\begin_inset space ~
+\end_inset
+
+to
+\begin_inset space ~
+\end_inset
+
+63 Feature bits reserved for future extensions
\end_layout
\begin_layout Standard
@@ -1407,6 +1625,19 @@ This allows for forwards and backwards compatibility: if the device is enhanced
support, it will not see that feature bit in the Device Features field
and can go into backwards compatibility mode (or, for poor implementations,
set the FAILED Device Status bit).
+\change_inserted 0 1304329423
+
+\end_layout
+
+\begin_layout Standard
+
+\change_inserted 0 1304331742
+Access to feature bits 32 to 63 is enabled by Guest by setting feature bit
+ 31.
+ If this bit is unset, Device must assume that all feature bits > 31 are
+ unset.
+\change_unchanged
+
\end_layout
\begin_layout Subsubsection
@@ -1891,7 +2122,38 @@ flags
field is currently 0 or 1: 1 indicating that we do not need an interrupt
when the device consumes a descriptor from the available ring.
- This interrupt suppression is merely an optimization; it may not suppress
+
+\change_inserted 0 1304540481
+Alternatively, the guest ask the device to delay interrupts until an entry
+ with an index specified by the
+\begin_inset Quotes eld
+\end_inset
+
+used_event
+\begin_inset Quotes erd
+\end_inset
+
+ field is written in the used ring (equivalently, until the
+\emph on
+idx
+\emph default
+ field in the used ring will reach the value
+\emph on
+used_event + 1
+\emph default
+).
+ The method employed by the device is controlled by the VIRTIO_RING_F_USED_EVENT
+_IDX feature bit (see
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "cha:Reserved-Feature-Bits"
+
+\end_inset
+
+).
+
+\change_unchanged
+This interrupt suppression is merely an optimization; it may not suppress
interrupts entirely.
\end_layout
@@ -1940,6 +2202,17 @@ struct vring_avail {
\begin_layout Plain Layout
u16 ring[qsz]; /* qsz is the Queue Size field read from device */
+\change_inserted 0 1304329945
+
+\end_layout
+
+\begin_layout Plain Layout
+
+\change_inserted 0 1304329957
+
+ u16 used_event;
+\change_unchanged
+
\end_layout
\begin_layout Plain Layout
@@ -1963,8 +2236,71 @@ The used ring is where the device returns buffers once it is done with them.
\emph on
available
\emph default
- ring (the flag is kept here because this is the only part of the virtqueue
- written by the device).
+ ring
+\change_inserted 0 1304540575
+.
+ Alternatively, the
+\begin_inset Quotes eld
+\end_inset
+
+avail_event
+\begin_inset Quotes erd
+\end_inset
+
+ field can be used by the device to hint that no notification is necessary
+ until an entry with an index specified by the
+\begin_inset Quotes eld
+\end_inset
+
+avail_event
+\begin_inset Quotes erd
+\end_inset
+
+ is written in the available ring (equivalently, until the
+\emph on
+idx
+\emph default
+ field in the available ring will reach the value
+\emph on
+avail_event + 1
+\emph default
+).
+
+\change_unchanged
+
+\change_inserted 0 1304540614
+The method employed by the device is controlled by the guest through the
+ VIRTIO_RING_F_AVAIL_EVENT_IDX feature bit (see
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "cha:Reserved-Feature-Bits"
+
+\end_inset
+
+).
+
+\change_deleted 0 1304331235
+(the flag is kept here because this is the only part of the virtqueue written
+ by the device)
+\change_inserted 0 1304540560
+
+\begin_inset Foot
+status open
+
+\begin_layout Plain Layout
+
+\change_inserted 0 1304331235
+These fields are kept here because this is the only part of the virtqueue
+ written by the device
+\change_unchanged
+
+\end_layout
+
+\end_inset
+
+
+\change_unchanged
+.
\end_layout
\begin_layout Standard
@@ -2046,6 +2382,17 @@ struct vring_used {
\begin_layout Plain Layout
struct vring_used_elem ring[qsz];
+\change_inserted 0 1304330369
+
+\end_layout
+
+\begin_layout Plain Layout
+
+\change_inserted 0 1304330380
+
+ u16 avail_event;
+\change_unchanged
+
\end_layout
\begin_layout Plain Layout
@@ -2065,9 +2412,13 @@ Helpers for Managing Virtqueues
\begin_layout Standard
The Linux Kernel Source code contains the definitions above and helper routines
in a more usable form, in include/linux/virtio_ring.h.
- This was explicitly licensed by IBM under the (3-clause) BSD license so
- that it can be freely used by all other projects, and is reproduced (with
- slight variation to remove Linux assumptions) in Appendix A.
+ This was explicitly licensed by IBM
+\change_inserted 0 1304342159
+and Red Hat
+\change_unchanged
+under the (3-clause) BSD license so that it can be freely used by all other
+ projects, and is reproduced (with slight variation to remove Linux assumptions)
+ in Appendix A.
\end_layout
\begin_layout Section
@@ -2374,12 +2725,61 @@ before
\emph default
checking the suppression flag: it's OK to notify gratuitously, but not
to omit a required notification.
- So again, we use a memory barrier here before reading the flags.
+ So again, we use a memory barrier here before reading the flags
+\change_inserted 0 1304336099
+ or the avail_event field
+\change_unchanged
+.
+\end_layout
+
+\begin_layout Standard
+If
+\change_inserted 0 1304336234
+the VIRTIO_ F_RING_AVAIL_EVENT_IDX feature is not negotiated, and if
+\change_unchanged
+the VRING_USED_F_NOTIFY flag is not set, we go ahead and write to the PCI
+ configuration space.
+\change_inserted 0 1304336255
+
+\end_layout
+
+\begin_layout Standard
+
+\change_inserted 0 1304336617
+If the VIRTIO_ F_RING_AVAIL_EVENT_IDX feature is negotiated, we read the
+ avail_event field in the available ring structure.
+ If the available index crossed_the
+\emph on
+avail_event
+\emph default
+ field value since the last notification, we go ahead and write to the PCI
+ configuration space.
+ The
+\emph on
+avail_event
+\emph default
+ field wraps naturally at 65536 as well:
\end_layout
\begin_layout Standard
-If the VRING_USED_F_NOTIFY flag is not set, we go ahead and write to the
- PCI configuration space.
+
+\change_inserted 0 1304336524
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+\change_inserted 0 1304336569
+
+(u16)(new_idx - avail_event - 1) < (u16)(new_idx - old_idx)
+\end_layout
+
+\end_inset
+
+
+\change_unchanged
+
\end_layout
\begin_layout Subsection
@@ -2408,8 +2808,66 @@ Update the used ring idx.
\end_layout
\begin_layout Enumerate
-If the VRING_AVAIL_F_NO_INTERRUPT flag is not set in avail\SpecialChar \nobreakdash-
->flags:
+
+\change_inserted 0 1304336736
+Determine whether an interrupt is necessary:
+\end_layout
+
+\begin_deeper
+\begin_layout Enumerate
+
+\change_inserted 0 1304336780
+If the VIRTIO_F_RING_USED_IDX is not negotiated: check if
+\change_deleted 0 1304336781
+I
+\change_unchanged
+f the VRING_AVAIL_F_NO_INTERRUPT flag is not set in avail\SpecialChar \nobreakdash-
+>flags
+\change_inserted 0 1304336788
+
+\end_layout
+
+\begin_layout Enumerate
+
+\change_deleted 0 1304336785
+:
+\change_inserted 0 1304336896
+If the VIRTIO_F_RING_USED_IDX is negotiated: check whether the used index
+ crossed the
+\emph on
+used_event
+\emph default
+ field value since the last update.
+ The
+\emph on
+used_event
+\emph default
+ field wraps naturally at 65536 as well:
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+\change_inserted 0 1304336902
+
+(u16)(new_idx - used_event - 1) < (u16)(new_idx - old_idx)
+\end_layout
+
+\end_inset
+
+
+\change_unchanged
+
+\end_layout
+
+\end_deeper
+\begin_layout Enumerate
+
+\change_inserted 0 1304336714
+If an interrupt is necessary:
+\change_unchanged
+
\end_layout
\begin_deeper
@@ -2464,13 +2922,87 @@ If MSI-X capability is enabled: look through the used rings of each virtqueue
\end_layout
\begin_layout Standard
+
+\change_inserted 0 1304341856
+For each ring, guest should then disable interrupts by writing VRING_AVAIL_F_NO_
+INTERRUPT flag in avail structure, if required.
+ It can then process used ring entries finally enabling interrupts by clearing
+ the VRING_AVAIL_F_NO_INTERRUPT flag or updating the used_idx field in the
+ available structure, Guest should then execute a memory barrier, and then
+ recheck the ring empty condition.
+ This is necessary to handle the case where, after the last check and before
+ enabling interrupts, an interrupt has been suppressed by the device:
+\end_layout
+
+\begin_layout Standard
\begin_inset listings
inline false
status open
\begin_layout Plain Layout
-while (vq->last_seen_used != vring->used.idx) {
+\change_inserted 0 1304342051
+
+vring_disable_interrupts(vq);
+\end_layout
+
+\begin_layout Plain Layout
+
+\change_inserted 0 1304341878
+
+for (;;) {
+\end_layout
+
+\begin_layout Plain Layout
+
+\change_inserted 0 1304341880
+
+ if
+\change_deleted 0 1304341882
+while
+\change_unchanged
+(vq->last_seen_used != vring->used.idx) {
+\change_inserted 0 1304341888
+
+\end_layout
+
+\begin_layout Plain Layout
+
+\change_inserted 0 1304342047
+
+ vring_enable_interrupts(vq);
+\end_layout
+
+\begin_layout Plain Layout
+
+\change_inserted 0 1304341986
+
+ mb();
+\end_layout
+
+\begin_layout Plain Layout
+
+\change_inserted 0 1304341964
+
+ if (vq->last_seen_used != vring->used.idx)
+\end_layout
+
+\begin_layout Plain Layout
+
+\change_inserted 0 1304341974
+
+ break;
+\change_unchanged
+
+\end_layout
+
+\begin_layout Plain Layout
+
+\change_inserted 0 1304341887
+
+ }
+\change_unchanged
+
\end_layout
\begin_layout Plain Layout
@@ -2721,6 +3253,15 @@ status open
\begin_layout Plain Layout
* Copyright 2007, 2009, IBM Corporation
+\change_inserted 0 1304341032
+
+\end_layout
+
+\begin_layout Plain Layout
+
+\change_inserted 0 1304341075
+
+ * Copyright 2011, Red Hat, Inc
\end_layout
\begin_layout Plain Layout
@@ -3019,6 +3560,17 @@ struct vring_avail {
\begin_layout Plain Layout
uint16_t ring[];
+\change_inserted 0 1304340808
+
+\end_layout
+
+\begin_layout Plain Layout
+
+\change_inserted 0 1304340816
+
+ uint16_t used_event;
+\change_unchanged
+
\end_layout
\begin_layout Plain Layout
@@ -3090,6 +3642,17 @@ struct vring_used {
\begin_layout Plain Layout
struct vring_used_elem ring[];
+\change_inserted 0 1304340824
+
+\end_layout
+
+\begin_layout Plain Layout
+
+\change_inserted 0 1304340831
+
+ uint16_t avail_event;
+\change_unchanged
+
\end_layout
\begin_layout Plain Layout
@@ -3326,12 +3889,58 @@ static inline unsigned vring_size(unsigned int num, unsigned long align)
\begin_layout Plain Layout
- + sizeof(uint16_t)*2 + sizeof(struct vring_used_elem)*num;
+ + sizeof(uint16_t)*
+\change_deleted 0 1304340844
+2
+\change_inserted 0 1304340844
+3
+\change_unchanged
+ + sizeof(struct vring_used_elem)*num;
+\end_layout
+
+\begin_layout Plain Layout
+
+}
+\change_inserted 0 1304340918
+
+\end_layout
+
+\begin_layout Plain Layout
+
+\change_inserted 0 1304340918
+
+\end_layout
+
+\begin_layout Plain Layout
+
+\change_inserted 0 1304340987
+
+static inline int vring_need_event(uint16_t event_idx, uint16_t new_idx,
+ uint16_t old_idx)
+\end_layout
+
+\begin_layout Plain Layout
+
+\change_inserted 0 1304340944
+
+{
\end_layout
\begin_layout Plain Layout
+\change_inserted 0 1304341001
+
+ return (uint16_t)(new_idx - event_idx - 1) < (uint16_t)(new_idx
+ - old_idx);
+\end_layout
+
+\begin_layout Plain Layout
+
+\change_inserted 0 1304340938
+
}
+\change_unchanged
+
\end_layout
\begin_layout Plain Layout
@@ -3355,7 +3964,13 @@ Appendix B: Reserved Feature Bits
\end_layout
\begin_layout Standard
-Currently there are three device-independent feature bits defined:
+Currently there are
+\change_inserted 0 1304540655
+six
+\change_deleted 0 1304330657
+three
+\change_unchanged
+ device-independent feature bits defined:
\end_layout
\begin_layout Description
@@ -3365,7 +3980,11 @@ VIRTIO_F_NOTIFY_ON_EMPTY
(24) Negotiating this feature indicates that the driver wants an interrupt
if the device runs out of available descriptors on a virtqueue, even though
- interrupts are suppressed using the VRING_AVAIL_F_NO_INTERRUPT flag.
+ interrupts are suppressed using the VRING_AVAIL_F_NO_INTERRUPT flag
+\change_inserted 0 1304341161
+ or the used_event field
+\change_unchanged
+.
An example of this is the networking driver: it doesn't need to know every
time a packet is transmitted, but it does need to free the transmitted
packets a finite time after they are transmitted.
@@ -3390,6 +4009,31 @@ reference "sub:Indirect-Descriptors"
\end_layout
\begin_layout Description
+
+\change_inserted 0 1304331394
+VIRTIO_F_RING_USED_EVENT_IDX(29) This feature indicates that the device
+ should ignore the
+\emph on
+flags
+\emph default
+ field in the available ring structure.
+ Instead, the
+\emph on
+ used_event
+\emph default
+ field in this structure is used by guest to suppress device interrupts.
+ If unset, the device should ignore the
+\emph on
+used_event
+\emph default
+ field; the
+\emph on
+flags
+\emph default
+ field is used
+\end_layout
+
+\begin_layout Description
VIRTIO_F_BAD_FEATURE(30) This feature should never be negotiated by the
guest; doing so is an indication that the guest is faulty
\begin_inset Foot
@@ -3403,6 +4047,43 @@ An experimental virtio PCI driver contained in Linux version 2.6.25 had this
\end_inset
+\change_inserted 0 1304330854
+
+\end_layout
+
+\begin_layout Description
+
+\change_inserted 0 1304330961
+VIRTIO_F_FEATURES_HIGH(31) This feature indicates that the device supports
+ feature bits 32:63.
+ If unset, feature bits 32:63 are unset.
+\end_layout
+
+\begin_layout Description
+
+\change_inserted 0 1304331390
+VIRTIO_F_RING_AVAIL_EVENT_IDX(32) This feature indicates that the driver
+ should ignore the
+\emph on
+flags
+\emph default
+ field in the used ring structure.
+ Instead, the
+\emph on
+avail_event
+\emph default
+ field in this structure is used by the device to suppress notifications.
+ If unset, the device should ignore the
+\emph on
+avail_event
+\emph default
+ field; the
+\emph on
+flags
+\emph default
+ field is used
+\change_unchanged
+
\end_layout
\begin_layout Chapter*
--
1.7.5.53.gc233e
^ permalink raw reply related
* Re: [net-next-2.6 PATCH] can: make struct can_proto const
From: Oliver Hartkopp @ 2011-05-04 20:34 UTC (permalink / raw)
To: socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20110504044057.GC278-MxZ6Iy/zr/UdbCeoMzGj59i2O/JbrIOy@public.gmane.org>
On 04.05.2011 06:40, Kurt Van Dijck wrote:
> commit 53914b67993c724cec585863755c9ebc8446e83b had the
> same message. That commit did put everything in place but
> did not make can_proto const itself.
>
> Signed-off-by: Kurt Van Dijck <kurt.van.dijck-/BeEPy95v10@public.gmane.org>
>
Acked-by: Oliver Hartkopp <socketcan-fJ+pQTUTwRTk1uMJSBkQmQ@public.gmane.org>
Thanks Kurt!
> diff --git a/include/linux/can/core.h b/include/linux/can/core.h
> index 6f70a6d..5ce6b5d 100644
> --- a/include/linux/can/core.h
> +++ b/include/linux/can/core.h
> @@ -44,8 +44,8 @@ struct can_proto {
>
> /* function prototypes for the CAN networklayer core (af_can.c) */
>
> -extern int can_proto_register(struct can_proto *cp);
> -extern void can_proto_unregister(struct can_proto *cp);
> +extern int can_proto_register(const struct can_proto *cp);
> +extern void can_proto_unregister(const struct can_proto *cp);
>
> extern int can_rx_register(struct net_device *dev, canid_t can_id,
> canid_t mask,
> diff --git a/net/can/af_can.c b/net/can/af_can.c
> index a8dcaa4..5b52762 100644
> --- a/net/can/af_can.c
> +++ b/net/can/af_can.c
> @@ -84,7 +84,7 @@ static DEFINE_SPINLOCK(can_rcvlists_lock);
> static struct kmem_cache *rcv_cache __read_mostly;
>
> /* table of registered CAN protocols */
> -static struct can_proto *proto_tab[CAN_NPROTO] __read_mostly;
> +static const struct can_proto *proto_tab[CAN_NPROTO] __read_mostly;
> static DEFINE_MUTEX(proto_tab_lock);
>
> struct timer_list can_stattimer; /* timer for statistics update */
> @@ -115,9 +115,9 @@ static void can_sock_destruct(struct sock *sk)
> skb_queue_purge(&sk->sk_receive_queue);
> }
>
> -static struct can_proto *can_try_module_get(int protocol)
> +static const struct can_proto *can_try_module_get(int protocol)
> {
> - struct can_proto *cp;
> + const struct can_proto *cp;
>
> rcu_read_lock();
> cp = rcu_dereference(proto_tab[protocol]);
> @@ -132,7 +132,7 @@ static int can_create(struct net *net, struct socket *sock, int protocol,
> int kern)
> {
> struct sock *sk;
> - struct can_proto *cp;
> + const struct can_proto *cp;
> int err = 0;
>
> sock->state = SS_UNCONNECTED;
> @@ -691,7 +691,7 @@ drop:
> * -EBUSY protocol already in use
> * -ENOBUF if proto_register() fails
> */
> -int can_proto_register(struct can_proto *cp)
> +int can_proto_register(const struct can_proto *cp)
> {
> int proto = cp->protocol;
> int err = 0;
> @@ -728,7 +728,7 @@ EXPORT_SYMBOL(can_proto_register);
> * can_proto_unregister - unregister CAN transport protocol
> * @cp: pointer to CAN protocol structure
> */
> -void can_proto_unregister(struct can_proto *cp)
> +void can_proto_unregister(const struct can_proto *cp)
> {
> int proto = cp->protocol;
>
> diff --git a/net/can/bcm.c b/net/can/bcm.c
> index 8a6a05e..cced806 100644
> --- a/net/can/bcm.c
> +++ b/net/can/bcm.c
> @@ -1601,7 +1601,7 @@ static struct proto bcm_proto __read_mostly = {
> .init = bcm_init,
> };
>
> -static struct can_proto bcm_can_proto __read_mostly = {
> +static const struct can_proto bcm_can_proto = {
> .type = SOCK_DGRAM,
> .protocol = CAN_BCM,
> .ops = &bcm_ops,
> diff --git a/net/can/raw.c b/net/can/raw.c
> index 0eb39a7..dea99a6 100644
> --- a/net/can/raw.c
> +++ b/net/can/raw.c
> @@ -774,7 +774,7 @@ static struct proto raw_proto __read_mostly = {
> .init = raw_init,
> };
>
> -static struct can_proto raw_can_proto __read_mostly = {
> +static const struct can_proto raw_can_proto = {
> .type = SOCK_RAW,
> .protocol = CAN_RAW,
> .ops = &raw_ops,
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [net-next-2.6 PATCH] can: rename can_try_module_get to can_get_proto
From: Oliver Hartkopp @ 2011-05-04 20:35 UTC (permalink / raw)
To: socketcan-core, netdev
In-Reply-To: <20110504044204.GD278@e-circ.dyndns.org>
On 04.05.2011 06:42, Kurt Van Dijck wrote:
> can: rename can_try_module_get to can_get_proto
>
> can_try_module_get does return a struct can_proto.
> The name explains what is done in so much detail that a caller
> may not notice that a struct can_proto is locked/unlocked.
>
> Signed-off-by: Kurt Van Dijck <kurt.van.dijck@eia.be>
Acked-by: Oliver Hartkopp <socketcan@hartkopp.net>
>
> diff --git a/net/can/af_can.c b/net/can/af_can.c
> index 5b52762..094fc53 100644
> --- a/net/can/af_can.c
> +++ b/net/can/af_can.c
> @@ -115,7 +115,7 @@ static void can_sock_destruct(struct sock *sk)
> skb_queue_purge(&sk->sk_receive_queue);
> }
>
> -static const struct can_proto *can_try_module_get(int protocol)
> +static const struct can_proto *can_get_proto(int protocol)
> {
> const struct can_proto *cp;
>
> @@ -128,6 +128,11 @@ static const struct can_proto *can_try_module_get(int protocol)
> return cp;
> }
>
> +static inline void can_put_proto(const struct can_proto *cp)
> +{
> + module_put(cp->prot->owner);
> +}
> +
> static int can_create(struct net *net, struct socket *sock, int protocol,
> int kern)
> {
> @@ -143,7 +148,7 @@ static int can_create(struct net *net, struct socket *sock, int protocol,
> if (!net_eq(net, &init_net))
> return -EAFNOSUPPORT;
>
> - cp = can_try_module_get(protocol);
> + cp = can_get_proto(protocol);
>
> #ifdef CONFIG_MODULES
> if (!cp) {
> @@ -160,7 +165,7 @@ static int can_create(struct net *net, struct socket *sock, int protocol,
> printk(KERN_ERR "can: request_module "
> "(can-proto-%d) failed.\n", protocol);
>
> - cp = can_try_module_get(protocol);
> + cp = can_get_proto(protocol);
> }
> #endif
>
> @@ -195,7 +200,7 @@ static int can_create(struct net *net, struct socket *sock, int protocol,
> }
>
> errout:
> - module_put(cp->prot->owner);
> + can_put_proto(cp);
> return err;
> }
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH 00/18] virtio and vhost-net performance enhancements
From: Michael S. Tsirkin @ 2011-05-04 20:50 UTC (permalink / raw)
To: linux-kernel
Cc: Rusty Russell, Carsten Otte, Christian Borntraeger, linux390,
Martin Schwidefsky, Heiko Carstens, Shirley Ma, lguest,
linux-kernel, virtualization, netdev, linux-s390, kvm,
Krishna Kumar, Tom Lendacky, steved, habanero
OK, here's a large patchset that implements the virtio spec update that I
sent earlier. It supercedes the PUBLISH_USED_IDX patches
I sent out earlier.
I know it's a lot to ask but please test, and please consider for 2.6.40 :)
I see nice performance improvements: one run showed going from 12
to 18 Gbit/s host to guest with netperf, but I did not spend a lot
of time testing performance, so no guarantees it's not a fluke,
I hope others will try this out and report.
Pls note I will be away from keyboard for the next week.
Essentially we change virtio ring notification
hand-off to work like the one in Xen -
each side publishes an event index, the other one
notifies when it reaches that value -
With the one difference that event index starts at 0,
same as request index (in xen event index starts at 1).
Each side of the handoff has a feature bit independent
of the other one, so we can have e.g. interrupts
handled in the new way and exits in the old one.
This is actually what made the patchset larger:
we run out of feature bits so I had to add some more.
I tested various combinations of hosts and guests and
this code seems to be solid.
With the indexes in place it becomes possbile to request an event after
many requests (and not just on the next one as done now). This shall fix
the TX queue overrun which currently triggers a storm of interrupts.
The patches are mostly independent and can also be cherry-picked,
hopefully there won't be much need of that.
One dependency I'd like to note is on two cleanup patches:
the patch removing batching of available index updates
and the patch fixing ring capability checks in virtio-net.
This simplified code a bit and made the following patch simpler.
I could unwrap the dependency but prefer as is.
The patchset is on top of net-next which at the time
I last rebased was 15ecd03 - so roughly 2.6.39-rc2.
qemu patch will follow shortly.
Rusty, I think (in the hope it will come to that) it will be easier to
merge vhost and virtio bits in one go. Can all go in through your tree
(Dave in the past acked a very similar patch so should not be a problem)
or from me to Dave Miller.
I see nice performance improvements: e.g. from 12 to 18 Gbit/s host
to guest with netperf, but did not spend a lot of time testing
performance, and I will be away from keyboard for the next week.
I hope others will try this out and report.
Michael S. Tsirkin (17):
virtio: 64 bit features
virtio_test: update for 64 bit features
vhost: fix 64 bit features
virtio: don't delay avail index update
virtio: used event index interface
virtio_ring: avail event index interface
virtio ring: inline function to check for events
virtio_ring: support for used_event idx feature
virtio: use avail_event index
vhost: utilize used_event index
vhost: support avail_event idx
virtio_test: support used_event index
virtio_test: avail_event index support
virtio: add api for delayed callbacks
virtio_net: delay TX callbacks
virtio_net: fix TX capacity checks using new API
virtio_net: limit xmit polling
Shirley Ma (1):
virtio_ring: Add capacity check API
drivers/lguest/lguest_device.c | 8 +-
drivers/net/virtio_net.c | 25 ++++---
drivers/s390/kvm/kvm_virtio.c | 8 +-
drivers/vhost/net.c | 12 ++--
drivers/vhost/test.c | 6 +-
drivers/vhost/vhost.c | 139 ++++++++++++++++++++++++++++++----------
drivers/vhost/vhost.h | 30 ++++++---
drivers/virtio/virtio.c | 8 +-
drivers/virtio/virtio_pci.c | 34 ++++++++--
drivers/virtio/virtio_ring.c | 105 +++++++++++++++++++++++++++---
include/linux/virtio.h | 16 ++++-
include/linux/virtio_config.h | 15 +++--
include/linux/virtio_pci.h | 9 ++-
include/linux/virtio_ring.h | 30 ++++++++-
tools/virtio/virtio_test.c | 39 ++++++++++-
15 files changed, 377 insertions(+), 107 deletions(-)
--
1.7.5.53.gc233e
^ permalink raw reply
* [PATCH 01/18] virtio: 64 bit features
From: Michael S. Tsirkin @ 2011-05-04 20:50 UTC (permalink / raw)
To: linux-kernel
Cc: Rusty Russell, Carsten Otte, Christian Borntraeger, linux390,
Martin Schwidefsky, Heiko Carstens, Shirley Ma, lguest,
linux-kernel, virtualization, netdev, linux-s390, kvm,
Krishna Kumar, Tom Lendacky, steved, habanero
In-Reply-To: <cover.1304541918.git.mst@redhat.com>
Extend features to 64 bit so we can use more
transport bits.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
drivers/lguest/lguest_device.c | 8 ++++----
drivers/s390/kvm/kvm_virtio.c | 8 ++++----
drivers/virtio/virtio.c | 8 ++++----
drivers/virtio/virtio_pci.c | 34 ++++++++++++++++++++++++++++------
drivers/virtio/virtio_ring.c | 2 ++
include/linux/virtio.h | 2 +-
include/linux/virtio_config.h | 15 +++++++++------
include/linux/virtio_pci.h | 9 ++++++++-
8 files changed, 60 insertions(+), 26 deletions(-)
diff --git a/drivers/lguest/lguest_device.c b/drivers/lguest/lguest_device.c
index 69c84a1..d2d6953 100644
--- a/drivers/lguest/lguest_device.c
+++ b/drivers/lguest/lguest_device.c
@@ -93,17 +93,17 @@ static unsigned desc_size(const struct lguest_device_desc *desc)
}
/* This gets the device's feature bits. */
-static u32 lg_get_features(struct virtio_device *vdev)
+static u64 lg_get_features(struct virtio_device *vdev)
{
unsigned int i;
- u32 features = 0;
+ u64 features = 0;
struct lguest_device_desc *desc = to_lgdev(vdev)->desc;
u8 *in_features = lg_features(desc);
/* We do this the slow but generic way. */
- for (i = 0; i < min(desc->feature_len * 8, 32); i++)
+ for (i = 0; i < min(desc->feature_len * 8, 64); i++)
if (in_features[i / 8] & (1 << (i % 8)))
- features |= (1 << i);
+ features |= (1ull << i);
return features;
}
diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c
index 414427d..c56293c 100644
--- a/drivers/s390/kvm/kvm_virtio.c
+++ b/drivers/s390/kvm/kvm_virtio.c
@@ -79,16 +79,16 @@ static unsigned desc_size(const struct kvm_device_desc *desc)
}
/* This gets the device's feature bits. */
-static u32 kvm_get_features(struct virtio_device *vdev)
+static u64 kvm_get_features(struct virtio_device *vdev)
{
unsigned int i;
- u32 features = 0;
+ u64 features = 0;
struct kvm_device_desc *desc = to_kvmdev(vdev)->desc;
u8 *in_features = kvm_vq_features(desc);
- for (i = 0; i < min(desc->feature_len * 8, 32); i++)
+ for (i = 0; i < min(desc->feature_len * 8, 64); i++)
if (in_features[i / 8] & (1 << (i % 8)))
- features |= (1 << i);
+ features |= (1ull << i);
return features;
}
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index efb35aa..52b24d7 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -112,7 +112,7 @@ static int virtio_dev_probe(struct device *_d)
struct virtio_device *dev = container_of(_d,struct virtio_device,dev);
struct virtio_driver *drv = container_of(dev->dev.driver,
struct virtio_driver, driver);
- u32 device_features;
+ u64 device_features;
/* We have a driver! */
add_status(dev, VIRTIO_CONFIG_S_DRIVER);
@@ -124,14 +124,14 @@ static int virtio_dev_probe(struct device *_d)
memset(dev->features, 0, sizeof(dev->features));
for (i = 0; i < drv->feature_table_size; i++) {
unsigned int f = drv->feature_table[i];
- BUG_ON(f >= 32);
- if (device_features & (1 << f))
+ BUG_ON(f >= 64);
+ if (device_features & (1ull << f))
set_bit(f, dev->features);
}
/* Transport features always preserved to pass to finalize_features. */
for (i = VIRTIO_TRANSPORT_F_START; i < VIRTIO_TRANSPORT_F_END; i++)
- if (device_features & (1 << i))
+ if (device_features & (1ull << i))
set_bit(i, dev->features);
dev->config->finalize_features(dev);
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c
index 4fb5b2b..04b216f 100644
--- a/drivers/virtio/virtio_pci.c
+++ b/drivers/virtio/virtio_pci.c
@@ -44,6 +44,8 @@ struct virtio_pci_device
spinlock_t lock;
struct list_head virtqueues;
+ /* 64 bit features */
+ int features_hi;
/* MSI-X support */
int msix_enabled;
int intx_enabled;
@@ -103,26 +105,46 @@ static struct virtio_pci_device *to_vp_device(struct virtio_device *vdev)
}
/* virtio config->get_features() implementation */
-static u32 vp_get_features(struct virtio_device *vdev)
+static u64 vp_get_features(struct virtio_device *vdev)
{
struct virtio_pci_device *vp_dev = to_vp_device(vdev);
+ u32 flo, fhi;
- /* When someone needs more than 32 feature bits, we'll need to
+ /* When someone needs more than 32 feature bits, we need to
* steal a bit to indicate that the rest are somewhere else. */
- return ioread32(vp_dev->ioaddr + VIRTIO_PCI_HOST_FEATURES);
+ flo = ioread32(vp_dev->ioaddr + VIRTIO_PCI_HOST_FEATURES);
+ if (flo & (0x1 << VIRTIO_F_FEATURES_HI)) {
+ vp_dev->features_hi = 1;
+ iowrite32(0x1 << VIRTIO_F_FEATURES_HI,
+ vp_dev->ioaddr + VIRTIO_PCI_GUEST_FEATURES);
+ fhi = ioread32(vp_dev->ioaddr + VIRTIO_PCI_HOST_FEATURES_HI);
+ } else {
+ vp_dev->features_hi = 0;
+ fhi = 0;
+ }
+ return (((u64)fhi) << 32) | flo;
}
/* virtio config->finalize_features() implementation */
static void vp_finalize_features(struct virtio_device *vdev)
{
struct virtio_pci_device *vp_dev = to_vp_device(vdev);
+ u32 flo, fhi;
/* Give virtio_ring a chance to accept features. */
vring_transport_features(vdev);
- /* We only support 32 feature bits. */
- BUILD_BUG_ON(ARRAY_SIZE(vdev->features) != 1);
- iowrite32(vdev->features[0], vp_dev->ioaddr+VIRTIO_PCI_GUEST_FEATURES);
+ /* We only support 64 feature bits. */
+ BUILD_BUG_ON(ARRAY_SIZE(vdev->features) != 64 / BITS_PER_LONG);
+ flo = vdev->features[0];
+ fhi = vdev->features[64 / BITS_PER_LONG - 1] >> (BITS_PER_LONG - 32);
+ iowrite32(flo, vp_dev->ioaddr + VIRTIO_PCI_GUEST_FEATURES);
+ if (flo & (0x1 << VIRTIO_F_FEATURES_HI)) {
+ vp_dev->features_hi = 1;
+ iowrite32(fhi, vp_dev->ioaddr + VIRTIO_PCI_GUEST_FEATURES_HI);
+ } else {
+ vp_dev->features_hi = 0;
+ }
}
/* virtio config->get() implementation */
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index cc2f73e..059e02d 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -469,6 +469,8 @@ void vring_transport_features(struct virtio_device *vdev)
for (i = VIRTIO_TRANSPORT_F_START; i < VIRTIO_TRANSPORT_F_END; i++) {
switch (i) {
+ case VIRTIO_F_FEATURES_HI:
+ break;
case VIRTIO_RING_F_INDIRECT_DESC:
break;
default:
diff --git a/include/linux/virtio.h b/include/linux/virtio.h
index aff5b4f..718336b 100644
--- a/include/linux/virtio.h
+++ b/include/linux/virtio.h
@@ -105,7 +105,7 @@ struct virtio_device {
struct virtio_config_ops *config;
struct list_head vqs;
/* Note that this is a Linux set_bit-style bitmap. */
- unsigned long features[1];
+ unsigned long features[64 / BITS_PER_LONG];
void *priv;
};
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
index 800617b..b1a1981 100644
--- a/include/linux/virtio_config.h
+++ b/include/linux/virtio_config.h
@@ -18,16 +18,19 @@
/* We've given up on this device. */
#define VIRTIO_CONFIG_S_FAILED 0x80
-/* Some virtio feature bits (currently bits 28 through 31) are reserved for the
+/* Some virtio feature bits (currently bits 28 through 39) are reserved for the
* transport being used (eg. virtio_ring), the rest are per-device feature
* bits. */
#define VIRTIO_TRANSPORT_F_START 28
-#define VIRTIO_TRANSPORT_F_END 32
+#define VIRTIO_TRANSPORT_F_END 40
/* Do we get callbacks when the ring is completely used, even if we've
* suppressed them? */
#define VIRTIO_F_NOTIFY_ON_EMPTY 24
+/* Enables feature bits 32 to 63 (only really required for virtio_pci). */
+#define VIRTIO_F_FEATURES_HI 31
+
#ifdef __KERNEL__
#include <linux/err.h>
#include <linux/virtio.h>
@@ -72,7 +75,7 @@
* @del_vqs: free virtqueues found by find_vqs().
* @get_features: get the array of feature bits for this device.
* vdev: the virtio_device
- * Returns the first 32 feature bits (all we currently need).
+ * Returns the first 64 feature bits (all we currently need).
* @finalize_features: confirm what device features we'll be using.
* vdev: the virtio_device
* This gives the final feature bits for the device: it can change
@@ -92,7 +95,7 @@ struct virtio_config_ops {
vq_callback_t *callbacks[],
const char *names[]);
void (*del_vqs)(struct virtio_device *);
- u32 (*get_features)(struct virtio_device *vdev);
+ u64 (*get_features)(struct virtio_device *vdev);
void (*finalize_features)(struct virtio_device *vdev);
};
@@ -110,9 +113,9 @@ static inline bool virtio_has_feature(const struct virtio_device *vdev,
{
/* Did you forget to fix assumptions on max features? */
if (__builtin_constant_p(fbit))
- BUILD_BUG_ON(fbit >= 32);
+ BUILD_BUG_ON(fbit >= 64);
else
- BUG_ON(fbit >= 32);
+ BUG_ON(fbit >= 64);
if (fbit < VIRTIO_TRANSPORT_F_START)
virtio_check_driver_offered_feature(vdev, fbit);
diff --git a/include/linux/virtio_pci.h b/include/linux/virtio_pci.h
index 9a3d7c4..90f9725 100644
--- a/include/linux/virtio_pci.h
+++ b/include/linux/virtio_pci.h
@@ -55,9 +55,16 @@
/* Vector value used to disable MSI for queue */
#define VIRTIO_MSI_NO_VECTOR 0xffff
+/* An extended 32-bit r/o bitmask of the features supported by the host */
+#define VIRTIO_PCI_HOST_FEATURES_HI 24
+
+/* An extended 32-bit r/w bitmask of features activated by the guest */
+#define VIRTIO_PCI_GUEST_FEATURES_HI 28
+
/* The remaining space is defined by each driver as the per-driver
* configuration space */
-#define VIRTIO_PCI_CONFIG(dev) ((dev)->msix_enabled ? 24 : 20)
+#define VIRTIO_PCI_CONFIG(dev) ((dev)->features_hi ? 32 : \
+ (dev)->msix_enabled ? 24 : 20)
/* Virtio ABI version, this must match exactly */
#define VIRTIO_PCI_ABI_VERSION 0
--
1.7.5.53.gc233e
^ permalink raw reply related
* [PATCH 02/18] virtio_test: update for 64 bit features
From: Michael S. Tsirkin @ 2011-05-04 20:50 UTC (permalink / raw)
To: linux-kernel
Cc: Krishna Kumar, Carsten Otte, lguest, Shirley Ma, kvm, linux-s390,
netdev, habanero, Heiko Carstens, linux-kernel, virtualization,
steved, Christian Borntraeger, Tom Lendacky, Martin Schwidefsky,
linux390
In-Reply-To: <cover.1304541918.git.mst@redhat.com>
Extend the virtio_test tool so it can work with
64 bit features.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
tools/virtio/virtio_test.c | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c
index df0c6d2..9e65e6d 100644
--- a/tools/virtio/virtio_test.c
+++ b/tools/virtio/virtio_test.c
@@ -55,7 +55,6 @@ void vhost_vq_setup(struct vdev_info *dev, struct vq_info *info)
{
struct vhost_vring_state state = { .index = info->idx };
struct vhost_vring_file file = { .index = info->idx };
- unsigned long long features = dev->vdev.features[0];
struct vhost_vring_addr addr = {
.index = info->idx,
.desc_user_addr = (uint64_t)(unsigned long)info->vring.desc,
@@ -63,6 +62,10 @@ void vhost_vq_setup(struct vdev_info *dev, struct vq_info *info)
.used_user_addr = (uint64_t)(unsigned long)info->vring.used,
};
int r;
+ unsigned long long features = dev->vdev.features[0];
+ if (sizeof features > sizeof dev->vdev.features[0])
+ features |= ((unsigned long long)dev->vdev.features[1]) << 32;
+
r = ioctl(dev->control, VHOST_SET_FEATURES, &features);
assert(r >= 0);
state.num = info->vring.num;
@@ -107,7 +110,8 @@ static void vdev_info_init(struct vdev_info* dev, unsigned long long features)
int r;
memset(dev, 0, sizeof *dev);
dev->vdev.features[0] = features;
- dev->vdev.features[1] = features >> 32;
+ if (sizeof features > sizeof dev->vdev.features[0])
+ dev->vdev.features[1] = features >> 32;
dev->buf_size = 1024;
dev->buf = malloc(dev->buf_size);
assert(dev->buf);
--
1.7.5.53.gc233e
^ permalink raw reply related
* [PATCH 03/18] vhost: fix 64 bit features
From: Michael S. Tsirkin @ 2011-05-04 20:50 UTC (permalink / raw)
To: linux-kernel
Cc: Krishna Kumar, Carsten Otte, lguest, Shirley Ma, kvm, linux-s390,
netdev, habanero, Heiko Carstens, linux-kernel, virtualization,
steved, Christian Borntraeger, Tom Lendacky, Martin Schwidefsky,
linux390
In-Reply-To: <cover.1304541918.git.mst@redhat.com>
Update vhost_has_feature to make it work correctly for bit > 32.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
drivers/vhost/vhost.h | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
index b3363ae..0f1bf33 100644
--- a/drivers/vhost/vhost.h
+++ b/drivers/vhost/vhost.h
@@ -117,7 +117,7 @@ struct vhost_dev {
struct vhost_memory __rcu *memory;
struct mm_struct *mm;
struct mutex mutex;
- unsigned acked_features;
+ u64 acked_features;
struct vhost_virtqueue *vqs;
int nvqs;
struct file *log_file;
@@ -169,14 +169,14 @@ enum {
(1 << VIRTIO_NET_F_MRG_RXBUF),
};
-static inline int vhost_has_feature(struct vhost_dev *dev, int bit)
+static inline bool vhost_has_feature(struct vhost_dev *dev, int bit)
{
- unsigned acked_features;
+ u64 acked_features;
/* TODO: check that we are running from vhost_worker or dev mutex is
* held? */
acked_features = rcu_dereference_index_check(dev->acked_features, 1);
- return acked_features & (1 << bit);
+ return acked_features & (1ull << bit);
}
#endif
--
1.7.5.53.gc233e
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox