* [net-next-2.6 PATCH 05/15] igb: add combined function for setting rar and pool bits
From: Jeff Kirsher @ 2009-10-05 16:32 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20091005163058.32487.10125.stgit@localhost.localdomain>
From: Alexander Duyck <alexander.h.duyck@intel.com>
This patch adds igb_rar_qsel which sets the mac address and pool bits for a
given mac address in the receive address register table.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/igb_main.c | 63 ++++++++++++++++++++++++++++----------------
1 files changed, 40 insertions(+), 23 deletions(-)
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 714c3a4..bb0aacd 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -127,10 +127,10 @@ static void igb_vlan_rx_register(struct net_device *, struct vlan_group *);
static void igb_vlan_rx_add_vid(struct net_device *, u16);
static void igb_vlan_rx_kill_vid(struct net_device *, u16);
static void igb_restore_vlan(struct igb_adapter *);
+static void igb_rar_set_qsel(struct igb_adapter *, u8 *, u32 , u8);
static void igb_ping_all_vfs(struct igb_adapter *);
static void igb_msg_task(struct igb_adapter *);
static int igb_rcv_msg_from_vf(struct igb_adapter *, u32);
-static inline void igb_set_rah_pool(struct e1000_hw *, int , int);
static void igb_vmm_control(struct igb_adapter *);
static int igb_set_vf_mac(struct igb_adapter *adapter, int, unsigned char *);
static void igb_restore_vf_multicasts(struct igb_adapter *adapter);
@@ -168,16 +168,6 @@ static inline int igb_set_vf_rlpml(struct igb_adapter *adapter, int size,
return 0;
}
-static inline void igb_set_rah_pool(struct e1000_hw *hw, int pool, int entry)
-{
- u32 reg_data;
-
- reg_data = rd32(E1000_RAH(entry));
- reg_data &= ~E1000_RAH_POOL_MASK;
- reg_data |= E1000_RAH_POOL_1 << pool;;
- wr32(E1000_RAH(entry), reg_data);
-}
-
#ifdef CONFIG_PM
static int igb_suspend(struct pci_dev *, pm_message_t);
static int igb_resume(struct pci_dev *);
@@ -982,7 +972,6 @@ int igb_up(struct igb_adapter *adapter)
igb_configure_msix(adapter);
igb_vmm_control(adapter);
- igb_set_rah_pool(hw, adapter->vfs_allocated_count, 0);
igb_set_vmolr(hw, adapter->vfs_allocated_count);
/* Clear any pending interrupts. */
@@ -1769,7 +1758,6 @@ static int igb_open(struct net_device *netdev)
igb_configure(adapter);
igb_vmm_control(adapter);
- igb_set_rah_pool(hw, adapter->vfs_allocated_count, 0);
igb_set_vmolr(hw, adapter->vfs_allocated_count);
err = igb_request_irq(adapter);
@@ -2298,6 +2286,10 @@ static void igb_configure_rx(struct igb_adapter *adapter)
/* Set the default pool for the PF's first queue */
igb_configure_vt_default_pool(adapter);
+ /* set the correct pool for the PF default MAC address in entry 0 */
+ igb_rar_set_qsel(adapter, adapter->hw.mac.addr, 0,
+ adapter->vfs_allocated_count);
+
igb_rlpml_set(adapter);
/* Enable Receives */
@@ -2521,8 +2513,9 @@ static int igb_set_mac(struct net_device *netdev, void *p)
memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
memcpy(hw->mac.addr, addr->sa_data, netdev->addr_len);
- igb_rar_set(hw, hw->mac.addr, 0);
- igb_set_rah_pool(hw, adapter->vfs_allocated_count, 0);
+ /* set the correct pool for the new PF MAC address in entry 0 */
+ igb_rar_set_qsel(adapter, hw->mac.addr, 0,
+ adapter->vfs_allocated_count);
return 0;
}
@@ -2572,10 +2565,9 @@ static void igb_set_rx_mode(struct net_device *netdev)
list_for_each_entry(ha, &netdev->uc.list, list) {
if (!rar_entries)
break;
- igb_rar_set(hw, ha->addr, rar_entries);
- igb_set_rah_pool(hw, adapter->vfs_allocated_count,
- rar_entries);
- rar_entries--;
+ igb_rar_set_qsel(adapter, ha->addr,
+ rar_entries--,
+ adapter->vfs_allocated_count);
}
}
/* write the addresses in reverse order to avoid write combining */
@@ -4142,8 +4134,7 @@ static inline void igb_vf_reset_msg(struct igb_adapter *adapter, u32 vf)
igb_vf_reset_event(adapter, vf);
/* set vf mac address */
- igb_rar_set(hw, vf_mac, rar_entry);
- igb_set_rah_pool(hw, vf, rar_entry);
+ igb_rar_set_qsel(adapter, vf_mac, rar_entry, vf);
/* enable transmit and receive for vf */
reg = rd32(E1000_VFTE);
@@ -5532,6 +5523,33 @@ static void igb_io_resume(struct pci_dev *pdev)
igb_get_hw_control(adapter);
}
+static void igb_rar_set_qsel(struct igb_adapter *adapter, u8 *addr, u32 index,
+ u8 qsel)
+{
+ u32 rar_low, rar_high;
+ struct e1000_hw *hw = &adapter->hw;
+
+ /* HW expects these in little endian so we reverse the byte order
+ * from network order (big endian) to little endian
+ */
+ rar_low = ((u32) addr[0] | ((u32) addr[1] << 8) |
+ ((u32) addr[2] << 16) | ((u32) addr[3] << 24));
+ rar_high = ((u32) addr[4] | ((u32) addr[5] << 8));
+
+ /* Indicate to hardware the Address is Valid. */
+ rar_high |= E1000_RAH_AV;
+
+ if (hw->mac.type == e1000_82575)
+ rar_high |= E1000_RAH_POOL_1 * qsel;
+ else
+ rar_high |= E1000_RAH_POOL_1 << qsel;
+
+ wr32(E1000_RAL(index), rar_low);
+ wrfl();
+ wr32(E1000_RAH(index), rar_high);
+ wrfl();
+}
+
static int igb_set_vf_mac(struct igb_adapter *adapter,
int vf, unsigned char *mac_addr)
{
@@ -5542,8 +5560,7 @@ static int igb_set_vf_mac(struct igb_adapter *adapter,
memcpy(adapter->vf_data[vf].vf_mac_addresses, mac_addr, ETH_ALEN);
- igb_rar_set(hw, mac_addr, rar_entry);
- igb_set_rah_pool(hw, vf, rar_entry);
+ igb_rar_set_qsel(adapter, mac_addr, rar_entry, vf);
return 0;
}
^ permalink raw reply related
* [net-next-2.6 PATCH 07/15] igb: add support for 82576NS SerDes adapter
From: Jeff Kirsher @ 2009-10-05 16:33 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20091005163058.32487.10125.stgit@localhost.localdomain>
From: Alexander Duyck <alexander.h.duyck@intel.com>
This patch adds the device ID necessary to support the 82576NS SerDes
adapter.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/e1000_82575.c | 1 +
drivers/net/igb/e1000_hw.h | 1 +
drivers/net/igb/igb_main.c | 1 +
3 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index b8a88a8..e07f66c 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -81,6 +81,7 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
break;
case E1000_DEV_ID_82576:
case E1000_DEV_ID_82576_NS:
+ case E1000_DEV_ID_82576_NS_SERDES:
case E1000_DEV_ID_82576_FIBER:
case E1000_DEV_ID_82576_SERDES:
case E1000_DEV_ID_82576_QUAD_COPPER:
diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h
index 7b7898b..4e7850d 100644
--- a/drivers/net/igb/e1000_hw.h
+++ b/drivers/net/igb/e1000_hw.h
@@ -42,6 +42,7 @@ struct e1000_hw;
#define E1000_DEV_ID_82576_SERDES 0x10E7
#define E1000_DEV_ID_82576_QUAD_COPPER 0x10E8
#define E1000_DEV_ID_82576_NS 0x150A
+#define E1000_DEV_ID_82576_NS_SERDES 0x1518
#define E1000_DEV_ID_82576_SERDES_QUAD 0x150D
#define E1000_DEV_ID_82575EB_COPPER 0x10A7
#define E1000_DEV_ID_82575EB_FIBER_SERDES 0x10A9
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index fdbe332..83c0837 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -63,6 +63,7 @@ static const struct e1000_info *igb_info_tbl[] = {
static struct pci_device_id igb_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_NS), board_82575 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_NS_SERDES), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_FIBER), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES_QUAD), board_82575 },
^ permalink raw reply related
* [net-next-2.6 PATCH 08/15] igb: add function to handle mailbox lock
From: Jeff Kirsher @ 2009-10-05 16:33 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20091005163058.32487.10125.stgit@localhost.localdomain>
From: Alexander Duyck <alexander.h.duyck@intel.com>
Both the read and write mailbox functions need to acquire the mailbox lock.
Since that is the case we might as well combine both of the procedures into
one function so it is easier to maintain.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/e1000_mbx.c | 63 +++++++++++++++++++++++--------------------
1 files changed, 34 insertions(+), 29 deletions(-)
diff --git a/drivers/net/igb/e1000_mbx.c b/drivers/net/igb/e1000_mbx.c
index ed9058e..ef645f6 100644
--- a/drivers/net/igb/e1000_mbx.c
+++ b/drivers/net/igb/e1000_mbx.c
@@ -305,6 +305,30 @@ static s32 igb_check_for_rst_pf(struct e1000_hw *hw, u16 vf_number)
}
/**
+ * igb_obtain_mbx_lock_pf - obtain mailbox lock
+ * @hw: pointer to the HW structure
+ * @vf_number: the VF index
+ *
+ * return SUCCESS if we obtained the mailbox lock
+ **/
+static s32 igb_obtain_mbx_lock_pf(struct e1000_hw *hw, u16 vf_number)
+{
+ s32 ret_val = -E1000_ERR_MBX;
+ u32 p2v_mailbox;
+
+
+ /* Take ownership of the buffer */
+ wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU);
+
+ /* reserve mailbox for vf use */
+ p2v_mailbox = rd32(E1000_P2VMAILBOX(vf_number));
+ if (p2v_mailbox & E1000_P2VMAILBOX_PFU)
+ ret_val = 0;
+
+ return ret_val;
+}
+
+/**
* igb_write_mbx_pf - Places a message in the mailbox
* @hw: pointer to the HW structure
* @msg: The message buffer
@@ -316,27 +340,17 @@ static s32 igb_check_for_rst_pf(struct e1000_hw *hw, u16 vf_number)
static s32 igb_write_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
u16 vf_number)
{
- u32 p2v_mailbox;
- s32 ret_val = 0;
+ s32 ret_val;
u16 i;
- /* Take ownership of the buffer */
- wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU);
-
- /* Make sure we have ownership now... */
- p2v_mailbox = rd32(E1000_P2VMAILBOX(vf_number));
- if (!(p2v_mailbox & E1000_P2VMAILBOX_PFU)) {
- /* failed to grab ownership */
- ret_val = -E1000_ERR_MBX;
+ /* lock the mailbox to prevent pf/vf race condition */
+ ret_val = igb_obtain_mbx_lock_pf(hw, vf_number);
+ if (ret_val)
goto out_no_write;
- }
- /*
- * flush any ack or msg which may already be in the queue
- * as they are likely the result of an error
- */
- igb_check_for_ack_pf(hw, vf_number);
+ /* flush msg and acks as we are overwriting the message buffer */
igb_check_for_msg_pf(hw, vf_number);
+ igb_check_for_ack_pf(hw, vf_number);
/* copy the caller specified message to the mailbox memory buffer */
for (i = 0; i < size; i++)
@@ -367,20 +381,13 @@ out_no_write:
static s32 igb_read_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
u16 vf_number)
{
- u32 p2v_mailbox;
- s32 ret_val = 0;
+ s32 ret_val;
u16 i;
- /* Take ownership of the buffer */
- wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU);
-
- /* Make sure we have ownership now... */
- p2v_mailbox = rd32(E1000_P2VMAILBOX(vf_number));
- if (!(p2v_mailbox & E1000_P2VMAILBOX_PFU)) {
- /* failed to grab ownership */
- ret_val = -E1000_ERR_MBX;
+ /* lock the mailbox to prevent pf/vf race condition */
+ ret_val = igb_obtain_mbx_lock_pf(hw, vf_number);
+ if (ret_val)
goto out_no_read;
- }
/* copy the message to the mailbox memory buffer */
for (i = 0; i < size; i++)
@@ -392,8 +399,6 @@ static s32 igb_read_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
/* update stats */
hw->mbx.stats.msgs_rx++;
- ret_val = 0;
-
out_no_read:
return ret_val;
}
^ permalink raw reply related
* [net-next-2.6 PATCH 09/15] igb: fix a few items where weren't correctly setup for mbx timeout
From: Jeff Kirsher @ 2009-10-05 16:34 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20091005163058.32487.10125.stgit@localhost.localdomain>
From: Alexander Duyck <alexander.h.duyck@intel.com>
The mailbox timeout routines need to be updated as they were not correctly
handling the case of a mailbox timeout and could cause issues with long
delays when used.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/e1000_mbx.c | 19 ++++++++++++++-----
1 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/drivers/net/igb/e1000_mbx.c b/drivers/net/igb/e1000_mbx.c
index ef645f6..c474cdb 100644
--- a/drivers/net/igb/e1000_mbx.c
+++ b/drivers/net/igb/e1000_mbx.c
@@ -143,12 +143,16 @@ static s32 igb_poll_for_msg(struct e1000_hw *hw, u16 mbx_id)
if (!countdown || !mbx->ops.check_for_msg)
goto out;
- while (mbx->ops.check_for_msg(hw, mbx_id)) {
+ while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) {
countdown--;
if (!countdown)
break;
udelay(mbx->usec_delay);
}
+
+ /* if we failed, all future posted messages fail until reset */
+ if (!countdown)
+ mbx->timeout = 0;
out:
return countdown ? 0 : -E1000_ERR_MBX;
}
@@ -168,12 +172,16 @@ static s32 igb_poll_for_ack(struct e1000_hw *hw, u16 mbx_id)
if (!countdown || !mbx->ops.check_for_ack)
goto out;
- while (mbx->ops.check_for_ack(hw, mbx_id)) {
+ while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) {
countdown--;
if (!countdown)
break;
udelay(mbx->usec_delay);
}
+
+ /* if we failed, all future posted messages fail until reset */
+ if (!countdown)
+ mbx->timeout = 0;
out:
return countdown ? 0 : -E1000_ERR_MBX;
}
@@ -217,12 +225,13 @@ out:
static s32 igb_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
{
struct e1000_mbx_info *mbx = &hw->mbx;
- s32 ret_val = 0;
+ s32 ret_val = -E1000_ERR_MBX;
- if (!mbx->ops.write)
+ /* exit if either we can't write or there isn't a defined timeout */
+ if (!mbx->ops.write || !mbx->timeout)
goto out;
- /* send msg*/
+ /* send msg */
ret_val = mbx->ops.write(hw, msg, size, mbx_id);
/* if msg sent wait until we receive an ack */
^ permalink raw reply related
* [net-next-2.6 PATCH 10/15] igb: change how we handle alternate mac addresses
From: Jeff Kirsher @ 2009-10-05 16:34 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20091005163058.32487.10125.stgit@localhost.localdomain>
From: Alexander Duyck <alexander.h.duyck@intel.com>
This patch allows us to treat the alternate mac address as though it is the
physical address on the adapter. This is accomplished by letting the
alt_mac_address function to only fail on an NVM error. If no errors occur
and the alternate mac address is not present then RAR0 is read as the
default mac address.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/e1000_82575.c | 13 +++++++++++--
drivers/net/igb/e1000_hw.h | 2 ++
drivers/net/igb/e1000_mac.c | 17 +++++++++--------
3 files changed, 22 insertions(+), 10 deletions(-)
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index e07f66c..45063c2 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -1152,9 +1152,18 @@ static s32 igb_read_mac_addr_82575(struct e1000_hw *hw)
{
s32 ret_val = 0;
- if (igb_check_alt_mac_addr(hw))
- ret_val = igb_read_mac_addr(hw);
+ /*
+ * If there's an alternate MAC address place it in RAR0
+ * so that it will override the Si installed default perm
+ * address.
+ */
+ ret_val = igb_check_alt_mac_addr(hw);
+ if (ret_val)
+ goto out;
+
+ ret_val = igb_read_mac_addr(hw);
+out:
return ret_val;
}
diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h
index 4e7850d..fad7cf5 100644
--- a/drivers/net/igb/e1000_hw.h
+++ b/drivers/net/igb/e1000_hw.h
@@ -54,6 +54,8 @@ struct e1000_hw;
#define E1000_FUNC_0 0
#define E1000_FUNC_1 1
+#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN1 3
+
enum e1000_mac_type {
e1000_undefined = 0,
e1000_82575,
diff --git a/drivers/net/igb/e1000_mac.c b/drivers/net/igb/e1000_mac.c
index 986aa90..4969a5b 100644
--- a/drivers/net/igb/e1000_mac.c
+++ b/drivers/net/igb/e1000_mac.c
@@ -185,13 +185,12 @@ s32 igb_check_alt_mac_addr(struct e1000_hw *hw)
}
if (nvm_alt_mac_addr_offset == 0xFFFF) {
- ret_val = -(E1000_NOT_IMPLEMENTED);
+ /* There is no Alternate MAC Address */
goto out;
}
if (hw->bus.func == E1000_FUNC_1)
- nvm_alt_mac_addr_offset += ETH_ALEN/sizeof(u16);
-
+ nvm_alt_mac_addr_offset += E1000_ALT_MAC_ADDRESS_OFFSET_LAN1;
for (i = 0; i < ETH_ALEN; i += 2) {
offset = nvm_alt_mac_addr_offset + (i >> 1);
ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data);
@@ -206,14 +205,16 @@ s32 igb_check_alt_mac_addr(struct e1000_hw *hw)
/* if multicast bit is set, the alternate address will not be used */
if (alt_mac_addr[0] & 0x01) {
- ret_val = -(E1000_NOT_IMPLEMENTED);
+ hw_dbg("Ignoring Alternate Mac Address with MC bit set\n");
goto out;
}
- for (i = 0; i < ETH_ALEN; i++)
- hw->mac.addr[i] = hw->mac.perm_addr[i] = alt_mac_addr[i];
-
- hw->mac.ops.rar_set(hw, hw->mac.perm_addr, 0);
+ /*
+ * We have a valid alternate MAC address, and we want to treat it the
+ * same as the normal permanent MAC address stored by the HW into the
+ * RAR. Do this by mapping this address into RAR0.
+ */
+ hw->mac.ops.rar_set(hw, alt_mac_addr, 0);
out:
return ret_val;
^ permalink raw reply related
* [net-next-2.6 PATCH 11/15] igb: remove microwire support from igb
From: Jeff Kirsher @ 2009-10-05 16:34 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20091005163058.32487.10125.stgit@localhost.localdomain>
From: Alexander Duyck <alexander.h.duyck@intel.com>
igb doesn't have any devices that use a microwire interface for NVM. As
such the code related to this can be removed.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/e1000_hw.h | 3 ---
drivers/net/igb/e1000_nvm.c | 36 +++---------------------------------
2 files changed, 3 insertions(+), 36 deletions(-)
diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h
index fad7cf5..2dc9294 100644
--- a/drivers/net/igb/e1000_hw.h
+++ b/drivers/net/igb/e1000_hw.h
@@ -74,7 +74,6 @@ enum e1000_nvm_type {
e1000_nvm_unknown = 0,
e1000_nvm_none,
e1000_nvm_eeprom_spi,
- e1000_nvm_eeprom_microwire,
e1000_nvm_flash_hw,
e1000_nvm_flash_sw
};
@@ -83,8 +82,6 @@ enum e1000_nvm_override {
e1000_nvm_override_none = 0,
e1000_nvm_override_spi_small,
e1000_nvm_override_spi_large,
- e1000_nvm_override_microwire_small,
- e1000_nvm_override_microwire_large
};
enum e1000_phy_type {
diff --git a/drivers/net/igb/e1000_nvm.c b/drivers/net/igb/e1000_nvm.c
index a88bfe2..d83b77f 100644
--- a/drivers/net/igb/e1000_nvm.c
+++ b/drivers/net/igb/e1000_nvm.c
@@ -78,9 +78,7 @@ static void igb_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count)
u32 mask;
mask = 0x01 << (count - 1);
- if (nvm->type == e1000_nvm_eeprom_microwire)
- eecd &= ~E1000_EECD_DO;
- else if (nvm->type == e1000_nvm_eeprom_spi)
+ if (nvm->type == e1000_nvm_eeprom_spi)
eecd |= E1000_EECD_DO;
do {
@@ -220,22 +218,7 @@ static void igb_standby_nvm(struct e1000_hw *hw)
struct e1000_nvm_info *nvm = &hw->nvm;
u32 eecd = rd32(E1000_EECD);
- if (nvm->type == e1000_nvm_eeprom_microwire) {
- eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
- wr32(E1000_EECD, eecd);
- wrfl();
- udelay(nvm->delay_usec);
-
- igb_raise_eec_clk(hw, &eecd);
-
- /* Select EEPROM */
- eecd |= E1000_EECD_CS;
- wr32(E1000_EECD, eecd);
- wrfl();
- udelay(nvm->delay_usec);
-
- igb_lower_eec_clk(hw, &eecd);
- } else if (nvm->type == e1000_nvm_eeprom_spi) {
+ if (nvm->type == e1000_nvm_eeprom_spi) {
/* Toggle CS to flush commands */
eecd |= E1000_EECD_CS;
wr32(E1000_EECD, eecd);
@@ -263,12 +246,6 @@ static void e1000_stop_nvm(struct e1000_hw *hw)
/* Pull CS high */
eecd |= E1000_EECD_CS;
igb_lower_eec_clk(hw, &eecd);
- } else if (hw->nvm.type == e1000_nvm_eeprom_microwire) {
- /* CS on Microcwire is active-high */
- eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
- wr32(E1000_EECD, eecd);
- igb_raise_eec_clk(hw, &eecd);
- igb_lower_eec_clk(hw, &eecd);
}
}
@@ -304,14 +281,7 @@ static s32 igb_ready_nvm_eeprom(struct e1000_hw *hw)
u8 spi_stat_reg;
- if (nvm->type == e1000_nvm_eeprom_microwire) {
- /* Clear SK and DI */
- eecd &= ~(E1000_EECD_DI | E1000_EECD_SK);
- wr32(E1000_EECD, eecd);
- /* Set CS */
- eecd |= E1000_EECD_CS;
- wr32(E1000_EECD, eecd);
- } else if (nvm->type == e1000_nvm_eeprom_spi) {
+ if (nvm->type == e1000_nvm_eeprom_spi) {
/* Clear SK and CS */
eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
wr32(E1000_EECD, eecd);
^ permalink raw reply related
* [net-next-2.6 PATCH 12/15] igb: move the generic copper link setup code into e1000_phy.c
From: Jeff Kirsher @ 2009-10-05 16:35 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20091005163058.32487.10125.stgit@localhost.localdomain>
From: Alexander Duyck <alexander.h.duyck@intel.com>
This patch moves the generic portion of the copper link setup into a
seperate function in e1000_phy.c. This helps to reduce the size of
copper_link_setup_82575 and make it a bit more readable.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/e1000_82575.c | 40 +--------------------------
drivers/net/igb/e1000_phy.c | 61 ++++++++++++++++++++++++++++++++++++++++-
drivers/net/igb/e1000_phy.h | 2 +
3 files changed, 62 insertions(+), 41 deletions(-)
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index 45063c2..5d345e3 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -907,7 +907,6 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
{
u32 ctrl;
s32 ret_val;
- bool link;
ctrl = rd32(E1000_CTRL);
ctrl |= E1000_CTRL_SLU;
@@ -940,44 +939,7 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
if (ret_val)
goto out;
- if (hw->mac.autoneg) {
- /*
- * Setup autoneg and flow control advertisement
- * and perform autonegotiation.
- */
- ret_val = igb_copper_link_autoneg(hw);
- if (ret_val)
- goto out;
- } else {
- /*
- * PHY will be set to 10H, 10F, 100H or 100F
- * depending on user settings.
- */
- hw_dbg("Forcing Speed and Duplex\n");
- ret_val = hw->phy.ops.force_speed_duplex(hw);
- if (ret_val) {
- hw_dbg("Error Forcing Speed and Duplex\n");
- goto out;
- }
- }
-
- /*
- * Check link status. Wait up to 100 microseconds for link to become
- * valid.
- */
- ret_val = igb_phy_has_link(hw, COPPER_LINK_UP_LIMIT, 10, &link);
- if (ret_val)
- goto out;
-
- if (link) {
- hw_dbg("Valid link established!!!\n");
- /* Config the MAC and PHY after link is up */
- igb_config_collision_dist(hw);
- ret_val = igb_config_fc_after_link_up(hw);
- } else {
- hw_dbg("Unable to establish link!!!\n");
- }
-
+ ret_val = igb_setup_copper_link(hw);
out:
return ret_val;
}
diff --git a/drivers/net/igb/e1000_phy.c b/drivers/net/igb/e1000_phy.c
index d4c928c..b27275d 100644
--- a/drivers/net/igb/e1000_phy.c
+++ b/drivers/net/igb/e1000_phy.c
@@ -669,7 +669,7 @@ out:
* and restart the negotiation process between the link partner. If
* autoneg_wait_to_complete, then wait for autoneg to complete before exiting.
**/
-s32 igb_copper_link_autoneg(struct e1000_hw *hw)
+static s32 igb_copper_link_autoneg(struct e1000_hw *hw)
{
struct e1000_phy_info *phy = &hw->phy;
s32 ret_val;
@@ -893,6 +893,65 @@ out:
}
/**
+ * igb_setup_copper_link - Configure copper link settings
+ * @hw: pointer to the HW structure
+ *
+ * Calls the appropriate function to configure the link for auto-neg or forced
+ * speed and duplex. Then we check for link, once link is established calls
+ * to configure collision distance and flow control are called. If link is
+ * not established, we return -E1000_ERR_PHY (-2).
+ **/
+s32 igb_setup_copper_link(struct e1000_hw *hw)
+{
+ s32 ret_val;
+ bool link;
+
+
+ if (hw->mac.autoneg) {
+ /*
+ * Setup autoneg and flow control advertisement and perform
+ * autonegotiation.
+ */
+ ret_val = igb_copper_link_autoneg(hw);
+ if (ret_val)
+ goto out;
+ } else {
+ /*
+ * PHY will be set to 10H, 10F, 100H or 100F
+ * depending on user settings.
+ */
+ hw_dbg("Forcing Speed and Duplex\n");
+ ret_val = hw->phy.ops.force_speed_duplex(hw);
+ if (ret_val) {
+ hw_dbg("Error Forcing Speed and Duplex\n");
+ goto out;
+ }
+ }
+
+ /*
+ * Check link status. Wait up to 100 microseconds for link to become
+ * valid.
+ */
+ ret_val = igb_phy_has_link(hw,
+ COPPER_LINK_UP_LIMIT,
+ 10,
+ &link);
+ if (ret_val)
+ goto out;
+
+ if (link) {
+ hw_dbg("Valid link established!!!\n");
+ igb_config_collision_dist(hw);
+ ret_val = igb_config_fc_after_link_up(hw);
+ } else {
+ hw_dbg("Unable to establish link!!!\n");
+ }
+
+out:
+ return ret_val;
+}
+
+/**
* igb_phy_force_speed_duplex_igp - Force speed/duplex for igp PHY
* @hw: pointer to the HW structure
*
diff --git a/drivers/net/igb/e1000_phy.h b/drivers/net/igb/e1000_phy.h
index 4c49803..adb9436 100644
--- a/drivers/net/igb/e1000_phy.h
+++ b/drivers/net/igb/e1000_phy.h
@@ -43,7 +43,6 @@ enum e1000_smart_speed {
s32 igb_check_downshift(struct e1000_hw *hw);
s32 igb_check_reset_block(struct e1000_hw *hw);
-s32 igb_copper_link_autoneg(struct e1000_hw *hw);
s32 igb_copper_link_setup_igp(struct e1000_hw *hw);
s32 igb_copper_link_setup_m88(struct e1000_hw *hw);
s32 igb_phy_force_speed_duplex_igp(struct e1000_hw *hw);
@@ -57,6 +56,7 @@ s32 igb_phy_sw_reset(struct e1000_hw *hw);
s32 igb_phy_hw_reset(struct e1000_hw *hw);
s32 igb_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data);
s32 igb_set_d3_lplu_state(struct e1000_hw *hw, bool active);
+s32 igb_setup_copper_link(struct e1000_hw *hw);
s32 igb_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data);
s32 igb_phy_has_link(struct e1000_hw *hw, u32 iterations,
u32 usec_interval, bool *success);
^ permalink raw reply related
* [net-next-2.6 PATCH 13/15] igb: add code to retry a phy read in the event of failure on link check
From: Jeff Kirsher @ 2009-10-05 16:35 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20091005163058.32487.10125.stgit@localhost.localdomain>
From: Alexander Duyck <alexander.h.duyck@intel.com>
This patch adds a retry to phy reads in the event of failure. The original
code broke out of the loop on failure and this is a mistake as we should be
trying to do the read twice.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/e1000_phy.c | 10 ++++++++--
1 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/net/igb/e1000_phy.c b/drivers/net/igb/e1000_phy.c
index b27275d..5fe03e1 100644
--- a/drivers/net/igb/e1000_phy.c
+++ b/drivers/net/igb/e1000_phy.c
@@ -1444,8 +1444,14 @@ s32 igb_phy_has_link(struct e1000_hw *hw, u32 iterations,
* it across the board.
*/
ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
- if (ret_val)
- break;
+ if (ret_val) {
+ /*
+ * If the first read fails, another entity may have
+ * ownership of the resources, wait and try again to
+ * see if they have relinquished the resources yet.
+ */
+ udelay(usec_interval);
+ }
ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
if (ret_val)
break;
^ permalink raw reply related
* [net-next-2.6 PATCH 14/15] igb: add additional error handling to the phy code
From: Jeff Kirsher @ 2009-10-05 16:35 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20091005163058.32487.10125.stgit@localhost.localdomain>
From: Alexander Duyck <alexander.h.duyck@intel.com>
This update adds additional exception handling to the phy code to handle
situations where it may be called incorrectly. In addition it adds some
bounds checking to the cable length checks to prevent an array overrun in
the event that the hardware returned a different value than expected.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/e1000_phy.c | 39 +++++++++++++++++++++++++--------------
1 files changed, 25 insertions(+), 14 deletions(-)
diff --git a/drivers/net/igb/e1000_phy.c b/drivers/net/igb/e1000_phy.c
index 5fe03e1..83b706c 100644
--- a/drivers/net/igb/e1000_phy.c
+++ b/drivers/net/igb/e1000_phy.c
@@ -39,6 +39,9 @@ static s32 igb_wait_autoneg(struct e1000_hw *hw);
/* Cable length tables */
static const u16 e1000_m88_cable_length_table[] =
{ 0, 50, 80, 110, 140, 140, E1000_CABLE_LENGTH_UNDEFINED };
+#define M88E1000_CABLE_LENGTH_TABLE_SIZE \
+ (sizeof(e1000_m88_cable_length_table) / \
+ sizeof(e1000_m88_cable_length_table[0]))
static const u16 e1000_igp_2_cable_length_table[] =
{ 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11, 13, 16, 18, 21,
@@ -109,7 +112,10 @@ out:
**/
static s32 igb_phy_reset_dsp(struct e1000_hw *hw)
{
- s32 ret_val;
+ s32 ret_val = 0;
+
+ if (!(hw->phy.ops.write_reg))
+ goto out;
ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xC1);
if (ret_val)
@@ -1059,22 +1065,19 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
igb_phy_force_speed_duplex_setup(hw, &phy_data);
- /* Reset the phy to commit changes. */
- phy_data |= MII_CR_RESET;
-
ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_data);
if (ret_val)
goto out;
- udelay(1);
+ /* Reset the phy to commit changes. */
+ ret_val = igb_phy_sw_reset(hw);
+ if (ret_val)
+ goto out;
if (phy->autoneg_wait_to_complete) {
hw_dbg("Waiting for forced speed/duplex link on M88 phy.\n");
- ret_val = igb_phy_has_link(hw,
- PHY_FORCE_LIMIT,
- 100000,
- &link);
+ ret_val = igb_phy_has_link(hw, PHY_FORCE_LIMIT, 100000, &link);
if (ret_val)
goto out;
@@ -1084,8 +1087,8 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
* Reset the DSP and cross our fingers.
*/
ret_val = phy->ops.write_reg(hw,
- M88E1000_PHY_PAGE_SELECT,
- 0x001d);
+ M88E1000_PHY_PAGE_SELECT,
+ 0x001d);
if (ret_val)
goto out;
ret_val = igb_phy_reset_dsp(hw);
@@ -1095,7 +1098,7 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
/* Try once more */
ret_val = igb_phy_has_link(hw, PHY_FORCE_LIMIT,
- 100000, &link);
+ 100000, &link);
if (ret_val)
goto out;
}
@@ -1207,9 +1210,12 @@ static void igb_phy_force_speed_duplex_setup(struct e1000_hw *hw,
s32 igb_set_d3_lplu_state(struct e1000_hw *hw, bool active)
{
struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
+ s32 ret_val = 0;
u16 data;
+ if (!(hw->phy.ops.read_reg))
+ goto out;
+
ret_val = phy->ops.read_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data);
if (ret_val)
goto out;
@@ -1495,8 +1501,13 @@ s32 igb_get_cable_length_m88(struct e1000_hw *hw)
index = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
M88E1000_PSSR_CABLE_LENGTH_SHIFT;
+ if (index >= M88E1000_CABLE_LENGTH_TABLE_SIZE - 1) {
+ ret_val = -E1000_ERR_PHY;
+ goto out;
+ }
+
phy->min_cable_length = e1000_m88_cable_length_table[index];
- phy->max_cable_length = e1000_m88_cable_length_table[index+1];
+ phy->max_cable_length = e1000_m88_cable_length_table[index + 1];
phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
^ permalink raw reply related
* [net-next-2.6 PATCH 15/15] igb: add flushes between RAR writes when setting mac address
From: Jeff Kirsher @ 2009-10-05 16:36 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20091005163058.32487.10125.stgit@localhost.localdomain>
From: Alexander Duyck <alexander.h.duyck@intel.com>
There are some switches that will do write combining when they see two
sequential regions written. In order to avoid any possible write combining
issues it is necessary to add a flush after writing each piece of a rar
register.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/e1000_mac.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/drivers/net/igb/e1000_mac.c b/drivers/net/igb/e1000_mac.c
index 4969a5b..2ad358a 100644
--- a/drivers/net/igb/e1000_mac.c
+++ b/drivers/net/igb/e1000_mac.c
@@ -247,8 +247,15 @@ void igb_rar_set(struct e1000_hw *hw, u8 *addr, u32 index)
if (rar_low || rar_high)
rar_high |= E1000_RAH_AV;
+ /*
+ * Some bridges will combine consecutive 32-bit writes into
+ * a single burst write, which will malfunction on some parts.
+ * The flushes avoid this.
+ */
wr32(E1000_RAL(index), rar_low);
+ wrfl();
wr32(E1000_RAH(index), rar_high);
+ wrfl();
}
/**
^ permalink raw reply related
* Re: [net-next-2.6 PATCH 6/9] vxge: Check if FCS stripping is disabled by the firmware.
From: Ben Greear @ 2009-10-05 16:44 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Sreenivasa Honnur, davem, netdev, support
In-Reply-To: <4AC9EEE0.5000601@gmail.com>
On 10/05/2009 06:04 AM, Eric Dumazet wrote:
> Sreenivasa Honnur a écrit :
>> - Added a function to check if FCS stripping is disabled by the firmware, if
>> it is not disabled fail driver load.
>>
>> - By default FCS stripping is disabled by the firmware. With this assumption
>> driver decrements the indicated packet length by 4 bytes(FCS length).
>>
>> - This patch ensures that FCS stripping is disabled during driver load time.
>>
>> Signed-off-by: Sreenivasa Honnur<sreenivasa.honnur@neterion.com>
>
> What the big deal about FCS not being stripped ?
I'd consider it a feature to be able to receive the CRC...would be nice for
sniffing applications!
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* Re: [PATCH] TCPCT+1: initial SYN exchange with SYNACK data
From: William Allen Simpson @ 2009-10-05 17:42 UTC (permalink / raw)
To: netdev
In-Reply-To: <20091005.014558.48061546.davem@davemloft.net>
David Miller wrote:
> Then we'll eat an atomic operation every connect() or something
> like that?
>
Yes, on the client side. On the server side, I was trying to avoid any
until after a 3-way handshake (the reason that I removed the kref'd struct
in Adam's request sock).
Adam:
+ struct tcp_sadata_payload *sadata_payload;
+ u8 sadata_nonce[4]; /* generated nonce */
+ u8 sadata_ok:1; /* send sadata? */
Mine:
+ u8 *cookie_copy; /* temporary pointer */
+ u8 cookie_size; /* bytes in copy */
+ u8 s_data_in:1,
+ s_data_out:1,
+ cookie_in_always:1,
+ cookie_out_never:1;
Mine makes the code more tricky, though. I'm depending on the various
locks and hashes to keep things kosher, whereas Adam kept more kref'd
pointer instances lying around for a longer time. Tradeoffs....
But I *was* patting myself on the back for saving 3 bytes here. ;-)
> That's bad too. We're trying desperately to remove as many
> atomic operations as possible from the socket paths.
>
And Adam had done a good job, too. The state has to go somewhere!
After all, I've plenty of experience with small TCP implementations, as
*all* implementations were constrained back in the day. At least one of
my tiny TCP/IP/PPP stack implementations is in hundreds of millions of
cell phones (originally on 186s with only a few K of RAM).
> Compress your state, really compress it, don't just externalize
> it somewhere else in exchange for a different cost.
>
Cookies are pseudo-random nonces, not compressible by definition.
I think I'll be able to join everything into a single kref'd block, with
some modification/reuse of various function md5sig parameters to pass
pointers.... Cookie nonces are redundant to the authenticator option(s),
so they're never around at the same time.
That will whittle the tcp_sock size down some more, although it could
increase the overall memory footprint, as there will be wasted space for
the case where there are cookies without SYN data. By keeping the sizes
and flags in the sock itself, both Adam and I were optimizing performance.
It's just tradeoffs, always and forever tradeoffs.
^ permalink raw reply
* Re: [PATCH] Use sk_mark for IPv6 routing lookups
From: Brian Haley @ 2009-10-05 18:24 UTC (permalink / raw)
To: Atis Elsts; +Cc: Maciej Żenczykowski, Eric Dumazet, David Miller, netdev
In-Reply-To: <200910051555.41543.atis@mikrotik.com>
Atis Elsts wrote:
> Not sure if there is need to fill the mark from skb in tunnel xmit functions. In any case, it's not done for GRE or IPIP tunnels at the moment.
Ok, I'll just drop that part, I'm not sure what should be done in this case.
> Also, in this patch you are doing that for SIT (v6-in-v4) tunnels only, and not doing it for v4-in-v6 or v6-in-v6 tunnels. Any reason for that?
I just sent that patch out too quickly, here's a better one with the updates.
Add support for IPv6 route lookups using sk_mark.
Signed-off-by: Brian Haley <brian.haley@hp.com>
---
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index e127a32..da36497 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -654,6 +654,7 @@ int inet6_sk_rebuild_header(struct sock *sk)
ipv6_addr_copy(&fl.fl6_src, &np->saddr);
fl.fl6_flowlabel = np->flow_label;
fl.oif = sk->sk_bound_dev_if;
+ fl.mark = sk->sk_mark;
fl.fl_ip_dport = inet->dport;
fl.fl_ip_sport = inet->sport;
security_sk_classify_flow(sk, &fl);
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index e2bdc6d..a615b4d 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -147,6 +147,7 @@ ipv4_connected:
ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
ipv6_addr_copy(&fl.fl6_src, &np->saddr);
fl.oif = sk->sk_bound_dev_if;
+ fl.mark = sk->sk_mark;
fl.fl_ip_dport = inet->dport;
fl.fl_ip_sport = inet->sport;
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c
index cc4797d..a9f4a21 100644
--- a/net/ipv6/inet6_connection_sock.c
+++ b/net/ipv6/inet6_connection_sock.c
@@ -194,6 +194,7 @@ int inet6_csk_xmit(struct sk_buff *skb, int ipfragok)
fl.fl6_flowlabel = np->flow_label;
IP6_ECN_flow_xmit(sk, fl.fl6_flowlabel);
fl.oif = sk->sk_bound_dev_if;
+ fl.mark = sk->sk_mark;
fl.fl_ip_sport = inet->sport;
fl.fl_ip_dport = inet->dport;
security_sk_classify_flow(sk, &fl);
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 14f54eb..dc0f736 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -424,6 +424,7 @@ sticky_done:
fl.fl6_flowlabel = 0;
fl.oif = sk->sk_bound_dev_if;
+ fl.mark = sk->sk_mark;
if (optlen == 0)
goto update;
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
index 6b6ae91..cbe55e5 100644
--- a/net/ipv6/syncookies.c
+++ b/net/ipv6/syncookies.c
@@ -252,6 +252,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
}
ipv6_addr_copy(&fl.fl6_src, &ireq6->loc_addr);
fl.oif = sk->sk_bound_dev_if;
+ fl.mark = sk->sk_mark;
fl.fl_ip_dport = inet_rsk(req)->rmt_port;
fl.fl_ip_sport = inet_sk(sk)->sport;
security_req_classify_flow(req, &fl);
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 21d100b..321aafd 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -243,6 +243,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
ipv6_addr_copy(&fl.fl6_src,
(saddr ? saddr : &np->saddr));
fl.oif = sk->sk_bound_dev_if;
+ fl.mark = sk->sk_mark;
fl.fl_ip_dport = usin->sin6_port;
fl.fl_ip_sport = inet->sport;
@@ -383,6 +384,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
ipv6_addr_copy(&fl.fl6_src, &np->saddr);
fl.oif = sk->sk_bound_dev_if;
+ fl.mark = sk->sk_mark;
fl.fl_ip_dport = inet->dport;
fl.fl_ip_sport = inet->sport;
security_skb_classify_flow(skb, &fl);
@@ -477,6 +479,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req)
ipv6_addr_copy(&fl.fl6_src, &treq->loc_addr);
fl.fl6_flowlabel = 0;
fl.oif = treq->iif;
+ fl.mark = sk->sk_mark;
fl.fl_ip_dport = inet_rsk(req)->rmt_port;
fl.fl_ip_sport = inet_rsk(req)->loc_port;
security_req_classify_flow(req, &fl);
@@ -1345,6 +1348,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
}
ipv6_addr_copy(&fl.fl6_src, &treq->loc_addr);
fl.oif = sk->sk_bound_dev_if;
+ fl.mark = sk->sk_mark;
fl.fl_ip_dport = inet_rsk(req)->rmt_port;
fl.fl_ip_sport = inet_rsk(req)->loc_port;
security_req_classify_flow(req, &fl);
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 3a60f12..3842c55 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -879,6 +879,8 @@ do_udp_sendmsg:
if (!fl.oif)
fl.oif = np->sticky_pktinfo.ipi6_ifindex;
+ fl.mark = sk->sk_mark;
+
if (msg->msg_controllen) {
opt = &opt_space;
memset(opt, 0, sizeof(struct ipv6_txoptions));
^ permalink raw reply related
* Re: [PATCH] Wireless / ath5k: Simplify suspend and resume callbacks
From: Rafael J. Wysocki @ 2009-10-05 19:40 UTC (permalink / raw)
To: Luis R. Rodriguez
Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA, ath5k-devel-xDcbHBWguxEUs3QNXV6qNA,
John W. Linville, LKML, pm list
In-Reply-To: <43e72e890910050921q7f516c67ofe17603d6d873c4-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Monday 05 October 2009, Luis R. Rodriguez wrote:
> On Sun, Oct 4, 2009 at 10:52 PM, Rafael J. Wysocki <rjw-KKrjLPT3xs0@public.gmane.org> wrote:
> > From: Rafael J. Wysocki <rjw-KKrjLPT3xs0@public.gmane.org>
> >
> > Simplify the suspend and resume callbacks of ath5k by converting the
> > driver to struct dev_pm_ops and allowing the PCI PM core to do the
> > PCI-specific suspend/resume handling.
> >
> > Signed-off-by: Rafael J. Wysocki <rjw-KKrjLPT3xs0@public.gmane.org>
>
> Do you happen to know if the new dev_pm_ops thing handle WOL / WoW [1]?
>
> [1] http://wireless.kernel.org/en/users/Documentation/WoW
It does enable wake-up at the PCI level if so configured, so in principle it
should handle it. However, for WoL to work there are some things that the
drivers is reponsible for, so I guess it will be analogous for WoW.
Anyway, the PCI-specific mechanics is there.
> > #ifdef CONFIG_PM
> > -static int
> > -ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state)
> > +static int ath5k_pci_suspend(struct device *dev)
> > {
> > - struct ieee80211_hw *hw = pci_get_drvdata(pdev);
> > + struct ieee80211_hw *hw = pci_get_drvdata(to_pci_dev(dev));
> > struct ath5k_softc *sc = hw->priv;
> >
> > ath5k_led_off(sc);
> > -
> > - pci_save_state(pdev);
> > - pci_disable_device(pdev);
>
> For WoW right here we'd do
>
> pci_prepare_to_sleep(pdev) and bail out.
>
> > - pci_set_power_state(pdev, PCI_D3hot);
>
> And here we'd call something like this:
>
> pci_wake_from_d3(pdev, !!sc->wow_triggers_enabled);
All of this is unnecessary, the PCI PM core should take care of this just
fine. In case it doesn't, it has to be fixed.
> > -
> > return 0;
> > }
>
> Are all drivers being converted?
Generally, yes, but that's not a priority work for me. I've just happened to
have the patch ready, so here it goes.
They should be converted, though, to be able to support PCI run-time PM.
> It'll be a while before we get WoW enabled on ath5k but it is
> technically possible, the work was tested for ath9k back in July [2]
> but I never submitted this to be merged due to some inconsistent
> issues I was noticing with the hardware.
>
> [2] http://kernel.org/pub/linux/kernel/people/mcgrof/patches/wow-07-21.patch
Thanks,
Rafael
^ permalink raw reply
* Re: [PATCH] dcb: data center bridging ops should be r/o
From: Peter P Waskiewicz Jr @ 2009-10-05 20:08 UTC (permalink / raw)
To: Stephen Hemminger
Cc: netdev@vger.kernel.org, e1000-devel@lists.sf.net, David Miller,
Kirsher, Jeffrey T, Jesse Brandeburg
In-Reply-To: <20091005090103.0340ef29@s6510>
On Mon, 2009-10-05 at 09:01 -0700, Stephen Hemminger wrote:
> The data center bridging ops structure can be const
>
> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
>
Thanks Stephen, that was an oversight.
Acked-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
> --- a/drivers/net/ixgbe/ixgbe.h 2009-10-03 21:40:25.712809970 -0700
> +++ b/drivers/net/ixgbe/ixgbe.h 2009-10-03 21:40:33.490342038 -0700
> @@ -397,7 +397,7 @@ enum ixgbe_boards {
> extern struct ixgbe_info ixgbe_82598_info;
> extern struct ixgbe_info ixgbe_82599_info;
> #ifdef CONFIG_IXGBE_DCB
> -extern struct dcbnl_rtnl_ops dcbnl_ops;
> +extern const struct dcbnl_rtnl_ops dcbnl_ops;
> extern int ixgbe_copy_dcb_cfg(struct ixgbe_dcb_config *src_dcb_cfg,
> struct ixgbe_dcb_config *dst_dcb_cfg,
> int tc_max);
> --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c 2009-10-03 21:39:54.710299317 -0700
> +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c 2009-10-03 21:40:05.990317034 -0700
> @@ -563,7 +563,7 @@ static u8 ixgbe_dcbnl_setapp(struct net_
> return rval;
> }
>
> -struct dcbnl_rtnl_ops dcbnl_ops = {
> +const struct dcbnl_rtnl_ops dcbnl_ops = {
> .getstate = ixgbe_dcbnl_get_state,
> .setstate = ixgbe_dcbnl_set_state,
> .getpermhwaddr = ixgbe_dcbnl_get_perm_hw_addr,
> --- a/include/linux/netdevice.h 2009-10-03 21:40:52.730300256 -0700
> +++ b/include/linux/netdevice.h 2009-10-03 21:41:10.362812001 -0700
> @@ -909,7 +909,7 @@ struct net_device
>
> #ifdef CONFIG_DCB
> /* Data Center Bridging netlink ops */
> - struct dcbnl_rtnl_ops *dcbnl_ops;
> + const struct dcbnl_rtnl_ops *dcbnl_ops;
> #endif
>
> #if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
> --
> 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
------------------------------------------------------------------------------
Come build with us! The BlackBerry® Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay
ahead of the curve. Join us from November 9-12, 2009. Register now!
http://p.sf.net/sfu/devconf
^ permalink raw reply
* [PATCH net-next-2.6] bonding: fix a parameter name in error message
From: Nicolas de Pesloüan @ 2009-10-05 20:11 UTC (permalink / raw)
To: netdev; +Cc: Jay Vosburgh, David Miller, bonding-devel
When parsing module parameters, bond_check_params() erroneously use 'xor_mode'
as the name of a module parameter in an error message.
The right name for this parameter is 'xmit_hash_policy'.
Signed-off-by: Nicolas de Pesloüan <nicolas.2p.debian@free.fr>
---
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 69c5b15..e061c86 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4665,7 +4665,8 @@ static int bond_check_params(struct bond_params *params)
if ((bond_mode != BOND_MODE_XOR) &&
(bond_mode != BOND_MODE_8023AD)) {
pr_info(DRV_NAME
- ": xor_mode param is irrelevant in mode %s\n",
+ ": xmit_hash_policy param is irrelevant in"
+ " mode %s\n",
bond_mode_name(bond_mode));
} else {
xmit_hashtype = bond_parse_parm(xmit_hash_policy,
^ permalink raw reply related
* [PATCH] ethtool: Add reset operation
From: Ben Hutchings @ 2009-10-05 20:59 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
After updating firmware stored in flash, users may wish to reset the
relevant hardware and start the new firmware immediately. This should
not be completely automatic as it may be disruptive.
A selective reset may also be useful for debugging or diagnostics.
This adds a separate reset operation which takes flags indicating the
components to be reset. Drivers are allowed to reset only a subset of
those requested, and must indicate the actual subset. This allows the
use of generic component masks and some future expansion.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
This differs from the previous (RFC) version only in the semantics of
the output value of the reset flags: they should indicate the components
which were *not* reset. This should be slightly less error-prone as it
means implementations do not need to maintain the input and output flags
separately.
Ben.
include/linux/ethtool.h | 32 ++++++++++++++++++++++++++++++++
net/core/ethtool.c | 23 +++++++++++++++++++++++
2 files changed, 55 insertions(+), 0 deletions(-)
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 15e4eb7..0ef1306 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -502,6 +502,7 @@ struct ethtool_ops {
int (*get_rxnfc)(struct net_device *, struct ethtool_rxnfc *, void *);
int (*set_rxnfc)(struct net_device *, struct ethtool_rxnfc *);
int (*flash_device)(struct net_device *, struct ethtool_flash *);
+ int (*reset)(struct net_device *, u32 *);
};
#endif /* __KERNEL__ */
@@ -559,6 +560,7 @@ struct ethtool_ops {
#define ETHTOOL_SRXCLSRLDEL 0x00000031 /* Delete RX classification rule */
#define ETHTOOL_SRXCLSRLINS 0x00000032 /* Insert RX classification rule */
#define ETHTOOL_FLASHDEV 0x00000033 /* Flash firmware to device */
+#define ETHTOOL_RESET 0x00000034 /* Reset hardware */
/* compatibility with older code */
#define SPARC_ETH_GSET ETHTOOL_GSET
@@ -689,4 +691,34 @@ struct ethtool_ops {
#define RX_CLS_FLOW_DISC 0xffffffffffffffffULL
+/* Reset flags */
+/* The reset() operation must clear the flags for the components which
+ * were actually reset. On successful return, the flags indicate the
+ * components which were not reset, either because they do not exist
+ * in the hardware or because they cannot be reset independently. The
+ * driver must never reset any components that were not requested.
+ */
+enum ethtool_reset_flags {
+ /* These flags represent components dedicated to the interface
+ * the command is addressed to. Shift any flag left by
+ * ETH_RESET_SHARED_SHIFT to reset a shared component of the
+ * same type.
+ */
+ ETH_RESET_MGMT = 1 << 0, /* Management processor */
+ ETH_RESET_IRQ = 1 << 1, /* Interrupt requester */
+ ETH_RESET_DMA = 1 << 2, /* DMA engine */
+ ETH_RESET_FILTER = 1 << 3, /* Filtering/flow direction */
+ ETH_RESET_OFFLOAD = 1 << 4, /* Protocol offload */
+ ETH_RESET_MAC = 1 << 5, /* Media access controller */
+ ETH_RESET_PHY = 1 << 6, /* Transceiver/PHY */
+ ETH_RESET_RAM = 1 << 7, /* RAM shared between
+ * multiple components */
+
+ ETH_RESET_DEDICATED = 0x0000ffff, /* All components dedicated to
+ * this interface */
+ ETH_RESET_ALL = 0xffffffff, /* All components used by this
+ * interface, even if shared */
+};
+#define ETH_RESET_SHARED_SHIFT 16
+
#endif /* _LINUX_ETHTOOL_H */
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 4c12ddb..6c7429c 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -309,6 +309,26 @@ static int ethtool_get_regs(struct net_device *dev, char __user *useraddr)
return ret;
}
+static int ethtool_reset(struct net_device *dev, char __user *useraddr)
+{
+ struct ethtool_value reset;
+ int ret;
+
+ if (!dev->ethtool_ops->reset)
+ return -EOPNOTSUPP;
+
+ if (copy_from_user(&reset, useraddr, sizeof(reset)))
+ return -EFAULT;
+
+ ret = dev->ethtool_ops->reset(dev, &reset.data);
+ if (ret)
+ return ret;
+
+ if (copy_to_user(useraddr, &reset, sizeof(reset)))
+ return -EFAULT;
+ return 0;
+}
+
static int ethtool_get_wol(struct net_device *dev, char __user *useraddr)
{
struct ethtool_wolinfo wol = { ETHTOOL_GWOL };
@@ -1127,6 +1147,9 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
case ETHTOOL_FLASHDEV:
rc = ethtool_flash_device(dev, useraddr);
break;
+ case ETHTOOL_RESET:
+ rc = ethtool_reset(dev, useraddr);
+ break;
default:
rc = -EOPNOTSUPP;
}
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH net-2.6] tg3: Fix phylib locking strategy
From: Matt Carlson @ 2009-10-05 21:09 UTC (permalink / raw)
To: Felix Radensky; +Cc: netdev, Michael Chan, andy
Felix, can you verify this solves your problem?
---
Felix Radensky noted that chip resets were generating stack trace dumps.
This is because the driver is attempting to acquire the mdio bus mutex
while holding the tp->lock spinlock. The fix is to change the code such
that every phy access takes the tp->lock spinlock instead.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
---
drivers/net/tg3.c | 37 ++++++++++++-------------------------
drivers/net/tg3.h | 1 -
2 files changed, 12 insertions(+), 26 deletions(-)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index f09bc5d..8afc60e 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -902,11 +902,12 @@ static int tg3_mdio_read(struct mii_bus *bp, int mii_id, int reg)
struct tg3 *tp = bp->priv;
u32 val;
- if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_PAUSED)
- return -EAGAIN;
+ spin_lock(&tp->lock);
if (tg3_readphy(tp, reg, &val))
- return -EIO;
+ val = -EIO;
+
+ spin_unlock(&tp->lock);
return val;
}
@@ -914,14 +915,16 @@ static int tg3_mdio_read(struct mii_bus *bp, int mii_id, int reg)
static int tg3_mdio_write(struct mii_bus *bp, int mii_id, int reg, u16 val)
{
struct tg3 *tp = bp->priv;
+ u32 ret = 0;
- if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_PAUSED)
- return -EAGAIN;
+ spin_lock(&tp->lock);
if (tg3_writephy(tp, reg, val))
- return -EIO;
+ ret = -EIO;
- return 0;
+ spin_unlock(&tp->lock);
+
+ return ret;
}
static int tg3_mdio_reset(struct mii_bus *bp)
@@ -1011,12 +1014,6 @@ static void tg3_mdio_config_5785(struct tg3 *tp)
static void tg3_mdio_start(struct tg3 *tp)
{
- if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) {
- mutex_lock(&tp->mdio_bus->mdio_lock);
- tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_PAUSED;
- mutex_unlock(&tp->mdio_bus->mdio_lock);
- }
-
tp->mi_mode &= ~MAC_MI_MODE_AUTO_POLL;
tw32_f(MAC_MI_MODE, tp->mi_mode);
udelay(80);
@@ -1041,15 +1038,6 @@ static void tg3_mdio_start(struct tg3 *tp)
tg3_mdio_config_5785(tp);
}
-static void tg3_mdio_stop(struct tg3 *tp)
-{
- if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) {
- mutex_lock(&tp->mdio_bus->mdio_lock);
- tp->tg3_flags3 |= TG3_FLG3_MDIOBUS_PAUSED;
- mutex_unlock(&tp->mdio_bus->mdio_lock);
- }
-}
-
static int tg3_mdio_init(struct tg3 *tp)
{
int i;
@@ -1141,7 +1129,6 @@ static void tg3_mdio_fini(struct tg3 *tp)
tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_INITED;
mdiobus_unregister(tp->mdio_bus);
mdiobus_free(tp->mdio_bus);
- tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_PAUSED;
}
}
@@ -6392,8 +6379,6 @@ static int tg3_chip_reset(struct tg3 *tp)
tg3_nvram_lock(tp);
- tg3_mdio_stop(tp);
-
tg3_ape_lock(tp, TG3_APE_LOCK_GRC);
/* No matching tg3_nvram_unlock() after this because
@@ -8698,6 +8683,8 @@ static int tg3_close(struct net_device *dev)
del_timer_sync(&tp->timer);
+ tg3_phy_stop(tp);
+
tg3_full_lock(tp, 1);
#if 0
tg3_dump_state(tp);
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 524691c..bab7940 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2748,7 +2748,6 @@ struct tg3 {
#define TG3_FLG3_5701_DMA_BUG 0x00000008
#define TG3_FLG3_USE_PHYLIB 0x00000010
#define TG3_FLG3_MDIOBUS_INITED 0x00000020
-#define TG3_FLG3_MDIOBUS_PAUSED 0x00000040
#define TG3_FLG3_PHY_CONNECTED 0x00000080
#define TG3_FLG3_RGMII_STD_IBND_DISABLE 0x00000100
#define TG3_FLG3_RGMII_EXT_IBND_RX_EN 0x00000200
--
1.6.4.4
^ permalink raw reply related
* Re: [PATCH 21/21] drivers/net/tlan.h: Convert printk(KERN_DEBUG to pr_dbg(
From: Rafael J. Wysocki @ 2009-10-05 21:15 UTC (permalink / raw)
To: Joe Perches; +Cc: David Miller, linux-kernel, chessman, netdev
In-Reply-To: <1254726974.1799.315.camel@Joe-Laptop.home>
On Monday 05 October 2009, Joe Perches wrote:
> On Mon, 2009-10-05 at 00:12 -0700, David Miller wrote:
> > From: Joe Perches <joe@perches.com>
> > Date: Sun, 4 Oct 2009 17:53:48 -0700
> > > Removed "TLAN: " prefix from debug printks, it's added by pr_fmt
> > > Signed-off-by: Joe Perches <joe@perches.com>
> > Applied to net-next-2.6
>
> Patches 20 and 21 depend on patch 1, which introduces pr_dbg
> to kernel.h. Compile failure otherwise.
Why don't you push the first patch first, then, and wait with the others until
it gets merged? This way individual subsystem maintainers will be able to
merge them cleanly.
Rafael
^ permalink raw reply
* Re: [PATCH RFC] isdn/capi: fix up CAPI subsystem workaround locking a bit
From: Michael Buesch @ 2009-10-05 21:24 UTC (permalink / raw)
To: Tilman Schmidt
Cc: i4ldeveloper, Carsten Paeth, Karsten Keil, Karsten Keil,
Armin Schindler, isdn4linux, netdev, linux-kernel
In-Reply-To: <4AC9DBA5.1090701@imap.cc>
On Monday 05 October 2009 13:42:29 Tilman Schmidt wrote:
> On Sat, 2009-10-03 20:35:19 +0200, Michael Buesch wrote:
>
> >> I remember that handle_minor_send() and/or handle_minor_recv() showed up
> >> in the crash backtraces. So if you move them out of the critical
> >> section, you can as well remove the lock completely.
> >
> > here's my original mail:
> > http://lkml.indiana.edu/hypermail/linux/kernel/0605.0/0455.html
> >
> > Note the patch in that mail does _not_ fix the issue, as it turned out later.
> > Then I did the workaround-lock patch, which _did_ fix it.
>
> Thanks for the info. So do I understand correctly that after:
>
> commit 6aa65472d18703064898eefb5eb58f7ecd0d8912
> Author: Michael Buesch <mb@bu3sch.de>
> Date: Mon Jun 26 00:25:30 2006 -0700
>
> [PATCH] CAPI crash / race condition
>
> you were actually still seeing LIST_POISON2 Oopses in
> capiminor_del_ack(), but after:
Yeah well. The oops with LIST_POISON was with a patch that converted the
datahandle_queue to struct list_head, but without the spinlock_t ackqlock added.
Then I added the spinlock_t ackqlock and it first seemed to fix the problem. (That
is the patch from the mail).
But it did only shrink the race window, so the crash did still happen, but less often.
The crash was only "fixed" with the workaround_lock patch (but _without_ any of the
ackqueue patches applied.)
> commit 053b47ff249b9e0a634dae807f81465205e7c228
> Author: Michael Buesch <mb@bu3sch.de>
> Date: Mon Feb 12 00:53:26 2007 -0800
>
> [PATCH] Workaround CAPI subsystem locking issue
>
> they were gone? That's interesting. I'll try to wrap my mind around
> this.
Yeah, this sledgehammer lock did fix the crash while leaving the old non-list-head
queue in place (it should still be there today).
> It's unfortunate that these crashes only seem to occur with one specific
> device (FritzCard DSL) which I don't have.
I still have the device somewhere. If you want to have it, I can blow off the
dust and send it to you. If you don't want it, I'll throw it away soon.
I'd really like to send it to you to get rid of it. ;)
> Can anyone shed some light on
> what that device is doing differently from other ISDN cards?
Well, it's a combined ISDN/DSL card, but I never used the ISDN part. So the crash
happened while transferring data over the DSL link.
The vendor driver is closed source with an open wrapper (like nvidia). It's a pretty
crappy unmaintained piece of software, but it ran stable with some patches applied
to the driver and the workaround-lock patch to the capi stack.
--
Greetings, Michael.
^ permalink raw reply
* Re: [PATCH 21/21] drivers/net/tlan.h: Convert printk(KERN_DEBUG to pr_dbg(
From: Joe Perches @ 2009-10-05 21:28 UTC (permalink / raw)
To: Rafael J. Wysocki; +Cc: David Miller, linux-kernel, chessman, netdev
In-Reply-To: <200910052315.01357.rjw@sisk.pl>
On Mon, 2009-10-05 at 23:15 +0200, Rafael J. Wysocki wrote:
> Why don't you push the first patch first, then, and wait with the others until
> it gets merged? This way individual subsystem maintainers will be able to
> merge them cleanly.
Sometimes patch series get a bit more feedback than individual patches.
Original rfc suggestion: (1 comment)
http://lkml.org/lkml/2009/10/1/399
Patch removing pr_fmt from driver (acked by Jiri):
http://lkml.org/lkml/2009/10/1/418
cheers, Joe
^ permalink raw reply
* Re: [PATCH net-2.6] tg3: Fix phylib locking strategy
From: Michael Chan @ 2009-10-05 21:29 UTC (permalink / raw)
To: Matt Carlson; +Cc: Felix Radensky, netdev@vger.kernel.org, andy@greyhouse.net
In-Reply-To: <1254777182.18287@xw6200>
On Mon, 2009-10-05 at 14:09 -0700, Matt Carlson wrote:
> Felix, can you verify this solves your problem?
>
> ---
>
> Felix Radensky noted that chip resets were generating stack trace dumps.
> This is because the driver is attempting to acquire the mdio bus mutex
> while holding the tp->lock spinlock. The fix is to change the code such
> that every phy access takes the tp->lock spinlock instead.
>
> Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
> ---
> drivers/net/tg3.c | 37 ++++++++++++-------------------------
> drivers/net/tg3.h | 1 -
> 2 files changed, 12 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
> index f09bc5d..8afc60e 100644
> --- a/drivers/net/tg3.c
> +++ b/drivers/net/tg3.c
> @@ -902,11 +902,12 @@ static int tg3_mdio_read(struct mii_bus *bp, int mii_id, int reg)
> struct tg3 *tp = bp->priv;
> u32 val;
>
> - if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_PAUSED)
> - return -EAGAIN;
> + spin_lock(&tp->lock);
>
Matt, do we need spin_lock_bh() here? The tp->lock can be taken in NAPI
poll BH context.
> if (tg3_readphy(tp, reg, &val))
> - return -EIO;
> + val = -EIO;
> +
> + spin_unlock(&tp->lock);
>
> return val;
> }
> @@ -914,14 +915,16 @@ static int tg3_mdio_read(struct mii_bus *bp, int mii_id, int reg)
> static int tg3_mdio_write(struct mii_bus *bp, int mii_id, int reg, u16 val)
> {
> struct tg3 *tp = bp->priv;
> + u32 ret = 0;
>
> - if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_PAUSED)
> - return -EAGAIN;
> + spin_lock(&tp->lock);
>
> if (tg3_writephy(tp, reg, val))
> - return -EIO;
> + ret = -EIO;
>
> - return 0;
> + spin_unlock(&tp->lock);
> +
> + return ret;
> }
>
> static int tg3_mdio_reset(struct mii_bus *bp)
> @@ -1011,12 +1014,6 @@ static void tg3_mdio_config_5785(struct tg3 *tp)
>
> static void tg3_mdio_start(struct tg3 *tp)
> {
> - if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) {
> - mutex_lock(&tp->mdio_bus->mdio_lock);
> - tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_PAUSED;
> - mutex_unlock(&tp->mdio_bus->mdio_lock);
> - }
> -
> tp->mi_mode &= ~MAC_MI_MODE_AUTO_POLL;
> tw32_f(MAC_MI_MODE, tp->mi_mode);
> udelay(80);
> @@ -1041,15 +1038,6 @@ static void tg3_mdio_start(struct tg3 *tp)
> tg3_mdio_config_5785(tp);
> }
>
> -static void tg3_mdio_stop(struct tg3 *tp)
> -{
> - if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) {
> - mutex_lock(&tp->mdio_bus->mdio_lock);
> - tp->tg3_flags3 |= TG3_FLG3_MDIOBUS_PAUSED;
> - mutex_unlock(&tp->mdio_bus->mdio_lock);
> - }
> -}
> -
> static int tg3_mdio_init(struct tg3 *tp)
> {
> int i;
> @@ -1141,7 +1129,6 @@ static void tg3_mdio_fini(struct tg3 *tp)
> tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_INITED;
> mdiobus_unregister(tp->mdio_bus);
> mdiobus_free(tp->mdio_bus);
> - tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_PAUSED;
> }
> }
>
> @@ -6392,8 +6379,6 @@ static int tg3_chip_reset(struct tg3 *tp)
>
> tg3_nvram_lock(tp);
>
> - tg3_mdio_stop(tp);
> -
> tg3_ape_lock(tp, TG3_APE_LOCK_GRC);
>
> /* No matching tg3_nvram_unlock() after this because
> @@ -8698,6 +8683,8 @@ static int tg3_close(struct net_device *dev)
>
> del_timer_sync(&tp->timer);
>
> + tg3_phy_stop(tp);
> +
> tg3_full_lock(tp, 1);
> #if 0
> tg3_dump_state(tp);
> diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
> index 524691c..bab7940 100644
> --- a/drivers/net/tg3.h
> +++ b/drivers/net/tg3.h
> @@ -2748,7 +2748,6 @@ struct tg3 {
> #define TG3_FLG3_5701_DMA_BUG 0x00000008
> #define TG3_FLG3_USE_PHYLIB 0x00000010
> #define TG3_FLG3_MDIOBUS_INITED 0x00000020
> -#define TG3_FLG3_MDIOBUS_PAUSED 0x00000040
> #define TG3_FLG3_PHY_CONNECTED 0x00000080
> #define TG3_FLG3_RGMII_STD_IBND_DISABLE 0x00000100
> #define TG3_FLG3_RGMII_EXT_IBND_RX_EN 0x00000200
^ permalink raw reply
* [net-2.6 PATCH 0/3] qlge: Fixes for qlge.
From: Ron Mercer @ 2009-10-05 21:46 UTC (permalink / raw)
To: davem; +Cc: netdev, ron.mercer
^ permalink raw reply
* [net-2.6 PATCH 1/3] qlge: Fix some bit definitions for reset register.
From: Ron Mercer @ 2009-10-05 21:46 UTC (permalink / raw)
To: davem; +Cc: netdev, ron.mercer
In-Reply-To: <1254779209-15174-1-git-send-email-ron.mercer@qlogic.com>
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
drivers/net/qlge/qlge.h | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
index 30d5585..f470fb9 100644
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -135,9 +135,9 @@ enum {
RST_FO_TFO = (1 << 0),
RST_FO_RR_MASK = 0x00060000,
RST_FO_RR_CQ_CAM = 0x00000000,
- RST_FO_RR_DROP = 0x00000001,
- RST_FO_RR_DQ = 0x00000002,
- RST_FO_RR_RCV_FUNC_CQ = 0x00000003,
+ RST_FO_RR_DROP = 0x00000002,
+ RST_FO_RR_DQ = 0x00000004,
+ RST_FO_RR_RCV_FUNC_CQ = 0x00000006,
RST_FO_FRB = (1 << 12),
RST_FO_MOP = (1 << 13),
RST_FO_REG = (1 << 14),
--
1.6.0.2
^ permalink raw reply related
* [net-2.6 PATCH 2/3] qlge: Fix queueing of firmware handler in ISR.
From: Ron Mercer @ 2009-10-05 21:46 UTC (permalink / raw)
To: davem; +Cc: netdev, ron.mercer
In-Reply-To: <1254779209-15174-1-git-send-email-ron.mercer@qlogic.com>
Check that we are not already polling firmware events before we queue the
firmware event worker, then disable firmware interrupts.
Otherwise we can queue the same event multiple times.
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
drivers/net/qlge/qlge_main.c | 8 +++++---
1 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 3d0efea..c21eda0 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -2001,15 +2001,17 @@ static irqreturn_t qlge_isr(int irq, void *dev_id)
/*
* Check MPI processor activity.
*/
- if (var & STS_PI) {
+ if ((var & STS_PI) &&
+ (ql_read32(qdev, INTR_MASK) & INTR_MASK_PI)) {
/*
* We've got an async event or mailbox completion.
* Handle it and clear the source of the interrupt.
*/
QPRINTK(qdev, INTR, ERR, "Got MPI processor interrupt.\n");
ql_disable_completion_interrupt(qdev, intr_context->intr);
- queue_delayed_work_on(smp_processor_id(), qdev->workqueue,
- &qdev->mpi_work, 0);
+ ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
+ queue_delayed_work_on(smp_processor_id(),
+ qdev->workqueue, &qdev->mpi_work, 0);
work_done++;
}
--
1.6.0.2
^ 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