* [PATCH 10/25] atm: Convert pci_table entries to PCI_VDEVICE (if PCI_ANY_ID is used)
From: Peter Huewe @ 2010-07-15 18:49 UTC (permalink / raw)
To: Kernel Janitors
Cc: Chas Williams, David S. Miller, Tejun Heo, linux-atm-general,
netdev, linux-kernel
From: Peter Huewe <peterhuewe@gmx.de>
This patch converts pci_table entries, where .subvendor=PCI_ANY_ID and
.subdevice=PCI_ANY_ID, .class=0 and .class_mask=0, to use the
PCI_VDEVICE macro, and thus improves readability.
Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
---
drivers/atm/zatm.c | 6 ++----
1 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c
index 702acce..4e885d2 100644
--- a/drivers/atm/zatm.c
+++ b/drivers/atm/zatm.c
@@ -1637,10 +1637,8 @@ out_free:
MODULE_LICENSE("GPL");
static struct pci_device_id zatm_pci_tbl[] __devinitdata = {
- { PCI_VENDOR_ID_ZEITNET, PCI_DEVICE_ID_ZEITNET_1221,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, ZATM_COPPER },
- { PCI_VENDOR_ID_ZEITNET, PCI_DEVICE_ID_ZEITNET_1225,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+ { PCI_VDEVICE(ZEITNET, PCI_DEVICE_ID_ZEITNET_1221), ZATM_COPPER },
+ { PCI_VDEVICE(ZEITNET, PCI_DEVICE_ID_ZEITNET_1225), 0 },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, zatm_pci_tbl);
--
1.7.1
^ permalink raw reply related
* [PATCH 09/25] atm: Convert pci_table entries to PCI_VDEVICE (if PCI_ANY_ID is used)
From: Peter Huewe @ 2010-07-15 18:48 UTC (permalink / raw)
To: Kernel Janitors
Cc: Chas Williams, David S. Miller, H Hartley Sweeten, Tejun Heo,
linux-atm-general, netdev, linux-kernel
From: Peter Huewe <peterhuewe@gmx.de>
This patch converts pci_table entries, where .subvendor=PCI_ANY_ID and
.subdevice=PCI_ANY_ID, .class=0 and .class_mask=0, to use the
PCI_VDEVICE macro, and thus improves readability.
Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
---
drivers/atm/nicstar.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c
index cff337e..729a149 100644
--- a/drivers/atm/nicstar.c
+++ b/drivers/atm/nicstar.c
@@ -264,8 +264,7 @@ static void __devexit nicstar_remove_one(struct pci_dev *pcidev)
}
static struct pci_device_id nicstar_pci_tbl[] __devinitdata = {
- {PCI_VENDOR_ID_IDT, PCI_DEVICE_ID_IDT_IDT77201,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ { PCI_VDEVICE(IDT, PCI_DEVICE_ID_IDT_IDT77201), 0 },
{0,} /* terminate list */
};
--
1.7.1
^ permalink raw reply related
* [PATCH 2/6] vxge: Fix multicast issues
From: Jon Mason @ 2010-07-15 18:47 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Sreenivasa Honnur, Ramkrishna Vepa
Fix error in multicast flag check, add calls to restore the status of
multicast and promiscuous mode settings after change_mtu, and style
cleanups to shorten the function calls by using a temporary variable.
Signed-off-by: Jon Mason <jon.mason@exar.com>
Signed-off-by: Sreenivasa Honnur <sreenivasa.honnur@exar.com>
Signed-off-by: Ramkrishna Vepa <ramkrishna.vepa@exar.com>
---
drivers/net/vxge/vxge-main.c | 270 +++++++++++++++++++++++-------------------
1 files changed, 146 insertions(+), 124 deletions(-)
diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c
index e78703d..66d914c 100644
--- a/drivers/net/vxge/vxge-main.c
+++ b/drivers/net/vxge/vxge-main.c
@@ -1088,7 +1088,8 @@ static void vxge_set_multicast(struct net_device *dev)
struct netdev_hw_addr *ha;
struct vxgedev *vdev;
int i, mcast_cnt = 0;
- struct __vxge_hw_device *hldev;
+ struct __vxge_hw_device *hldev;
+ struct vxge_vpath *vpath;
enum vxge_hw_status status = VXGE_HW_OK;
struct macInfo mac_info;
int vpath_idx = 0;
@@ -1108,46 +1109,48 @@ static void vxge_set_multicast(struct net_device *dev)
if ((dev->flags & IFF_ALLMULTI) && (!vdev->all_multi_flg)) {
for (i = 0; i < vdev->no_of_vpath; i++) {
- vxge_assert(vdev->vpaths[i].is_open);
- status = vxge_hw_vpath_mcast_enable(
- vdev->vpaths[i].handle);
+ vpath = &vdev->vpaths[i];
+ vxge_assert(vpath->is_open);
+ status = vxge_hw_vpath_mcast_enable(vpath->handle);
+ if (status != VXGE_HW_OK)
+ vxge_debug_init(VXGE_ERR, "failed to enable "
+ "multicast, status %d", status);
vdev->all_multi_flg = 1;
}
- } else if ((dev->flags & IFF_ALLMULTI) && (vdev->all_multi_flg)) {
+ } else if (!(dev->flags & IFF_ALLMULTI) && (vdev->all_multi_flg)) {
for (i = 0; i < vdev->no_of_vpath; i++) {
- vxge_assert(vdev->vpaths[i].is_open);
- status = vxge_hw_vpath_mcast_disable(
- vdev->vpaths[i].handle);
- vdev->all_multi_flg = 1;
+ vpath = &vdev->vpaths[i];
+ vxge_assert(vpath->is_open);
+ status = vxge_hw_vpath_mcast_disable(vpath->handle);
+ if (status != VXGE_HW_OK)
+ vxge_debug_init(VXGE_ERR, "failed to disable "
+ "multicast, status %d", status);
+ vdev->all_multi_flg = 0;
}
}
- if (status != VXGE_HW_OK)
- vxge_debug_init(VXGE_ERR,
- "failed to %s multicast, status %d",
- dev->flags & IFF_ALLMULTI ?
- "enable" : "disable", status);
if (!vdev->config.addr_learn_en) {
- if (dev->flags & IFF_PROMISC) {
- for (i = 0; i < vdev->no_of_vpath; i++) {
- vxge_assert(vdev->vpaths[i].is_open);
+ for (i = 0; i < vdev->no_of_vpath; i++) {
+ vpath = &vdev->vpaths[i];
+ vxge_assert(vpath->is_open);
+
+ if (dev->flags & IFF_PROMISC)
status = vxge_hw_vpath_promisc_enable(
- vdev->vpaths[i].handle);
- }
- } else {
- for (i = 0; i < vdev->no_of_vpath; i++) {
- vxge_assert(vdev->vpaths[i].is_open);
+ vpath->handle);
+ else
status = vxge_hw_vpath_promisc_disable(
- vdev->vpaths[i].handle);
- }
+ vpath->handle);
+ if (status != VXGE_HW_OK)
+ vxge_debug_init(VXGE_ERR, "failed to %s promisc"
+ ", status %d", dev->flags&IFF_PROMISC ?
+ "enable" : "disable", status);
}
}
memset(&mac_info, 0, sizeof(struct macInfo));
/* Update individual M_CAST address list */
if ((!vdev->all_multi_flg) && netdev_mc_count(dev)) {
-
mcast_cnt = vdev->vpaths[0].mcast_addr_cnt;
list_head = &vdev->vpaths[0].mac_addr_list;
if ((netdev_mc_count(dev) +
@@ -1157,14 +1160,7 @@ static void vxge_set_multicast(struct net_device *dev)
/* Delete previous MC's */
for (i = 0; i < mcast_cnt; i++) {
- if (!list_empty(list_head))
- mac_entry = (struct vxge_mac_addrs *)
- list_first_entry(list_head,
- struct vxge_mac_addrs,
- item);
-
list_for_each_safe(entry, next, list_head) {
-
mac_entry = (struct vxge_mac_addrs *) entry;
/* Copy the mac address to delete */
mac_address = (u8 *)&mac_entry->macaddr;
@@ -1207,9 +1203,7 @@ _set_all_mcast:
mcast_cnt = vdev->vpaths[0].mcast_addr_cnt;
/* Delete previous MC's */
for (i = 0; i < mcast_cnt; i++) {
-
list_for_each_safe(entry, next, list_head) {
-
mac_entry = (struct vxge_mac_addrs *) entry;
/* Copy the mac address to delete */
mac_address = (u8 *)&mac_entry->macaddr;
@@ -1229,9 +1223,10 @@ _set_all_mcast:
/* Enable all multicast */
for (i = 0; i < vdev->no_of_vpath; i++) {
- vxge_assert(vdev->vpaths[i].is_open);
- status = vxge_hw_vpath_mcast_enable(
- vdev->vpaths[i].handle);
+ vpath = &vdev->vpaths[i];
+ vxge_assert(vpath->is_open);
+
+ status = vxge_hw_vpath_mcast_enable(vpath->handle);
if (status != VXGE_HW_OK) {
vxge_debug_init(VXGE_ERR,
"%s:%d Enabling all multicasts failed",
@@ -1392,6 +1387,7 @@ void vxge_vpath_intr_disable(struct vxgedev *vdev, int vp_id)
static int vxge_reset_vpath(struct vxgedev *vdev, int vp_id)
{
enum vxge_hw_status status = VXGE_HW_OK;
+ struct vxge_vpath *vpath = &vdev->vpaths[vp_id];
int ret = 0;
/* check if device is down already */
@@ -1402,12 +1398,10 @@ static int vxge_reset_vpath(struct vxgedev *vdev, int vp_id)
if (test_bit(__VXGE_STATE_RESET_CARD, &vdev->state))
return 0;
- if (vdev->vpaths[vp_id].handle) {
- if (vxge_hw_vpath_reset(vdev->vpaths[vp_id].handle)
- == VXGE_HW_OK) {
+ if (vpath->handle) {
+ if (vxge_hw_vpath_reset(vpath->handle) == VXGE_HW_OK) {
if (is_vxge_card_up(vdev) &&
- vxge_hw_vpath_recover_from_reset(
- vdev->vpaths[vp_id].handle)
+ vxge_hw_vpath_recover_from_reset(vpath->handle)
!= VXGE_HW_OK) {
vxge_debug_init(VXGE_ERR,
"vxge_hw_vpath_recover_from_reset"
@@ -1423,11 +1417,20 @@ static int vxge_reset_vpath(struct vxgedev *vdev, int vp_id)
} else
return VXGE_HW_FAIL;
- vxge_restore_vpath_mac_addr(&vdev->vpaths[vp_id]);
- vxge_restore_vpath_vid_table(&vdev->vpaths[vp_id]);
+ vxge_restore_vpath_mac_addr(vpath);
+ vxge_restore_vpath_vid_table(vpath);
/* Enable all broadcast */
- vxge_hw_vpath_bcast_enable(vdev->vpaths[vp_id].handle);
+ vxge_hw_vpath_bcast_enable(vpath->handle);
+
+ /* Enable all multicast */
+ if (vdev->all_multi_flg) {
+ status = vxge_hw_vpath_mcast_enable(vpath->handle);
+ if (status != VXGE_HW_OK)
+ vxge_debug_init(VXGE_ERR,
+ "%s:%d Enabling multicast failed",
+ __func__, __LINE__);
+ }
/* Enable the interrupts */
vxge_vpath_intr_enable(vdev, vp_id);
@@ -1435,17 +1438,17 @@ static int vxge_reset_vpath(struct vxgedev *vdev, int vp_id)
smp_wmb();
/* Enable the flow of traffic through the vpath */
- vxge_hw_vpath_enable(vdev->vpaths[vp_id].handle);
+ vxge_hw_vpath_enable(vpath->handle);
smp_wmb();
- vxge_hw_vpath_rx_doorbell_init(vdev->vpaths[vp_id].handle);
- vdev->vpaths[vp_id].ring.last_status = VXGE_HW_OK;
+ vxge_hw_vpath_rx_doorbell_init(vpath->handle);
+ vpath->ring.last_status = VXGE_HW_OK;
/* Vpath reset done */
clear_bit(vp_id, &vdev->vp_reset);
/* Start the vpath queue */
- vxge_wake_tx_queue(&vdev->vpaths[vp_id].fifo);
+ vxge_wake_tx_queue(&vpath->fifo);
return ret;
}
@@ -1479,9 +1482,9 @@ static int do_vxge_reset(struct vxgedev *vdev, int event)
vxge_debug_init(VXGE_ERR,
"%s: execution mode is debug, returning..",
vdev->ndev->name);
- clear_bit(__VXGE_STATE_CARD_UP, &vdev->state);
- netif_tx_stop_all_queues(vdev->ndev);
- return 0;
+ clear_bit(__VXGE_STATE_CARD_UP, &vdev->state);
+ netif_tx_stop_all_queues(vdev->ndev);
+ return 0;
}
}
@@ -1628,8 +1631,7 @@ out:
*/
int vxge_reset(struct vxgedev *vdev)
{
- do_vxge_reset(vdev, VXGE_LL_FULL_RESET);
- return 0;
+ return do_vxge_reset(vdev, VXGE_LL_FULL_RESET);
}
/**
@@ -1992,17 +1994,17 @@ enum vxge_hw_status vxge_restore_vpath_mac_addr(struct vxge_vpath *vpath)
/* reset vpaths */
enum vxge_hw_status vxge_reset_all_vpaths(struct vxgedev *vdev)
{
- int i;
enum vxge_hw_status status = VXGE_HW_OK;
+ struct vxge_vpath *vpath;
+ int i;
- for (i = 0; i < vdev->no_of_vpath; i++)
- if (vdev->vpaths[i].handle) {
- if (vxge_hw_vpath_reset(vdev->vpaths[i].handle)
- == VXGE_HW_OK) {
+ for (i = 0; i < vdev->no_of_vpath; i++) {
+ vpath = &vdev->vpaths[i];
+ if (vpath->handle) {
+ if (vxge_hw_vpath_reset(vpath->handle) == VXGE_HW_OK) {
if (is_vxge_card_up(vdev) &&
vxge_hw_vpath_recover_from_reset(
- vdev->vpaths[i].handle)
- != VXGE_HW_OK) {
+ vpath->handle) != VXGE_HW_OK) {
vxge_debug_init(VXGE_ERR,
"vxge_hw_vpath_recover_"
"from_reset failed for vpath: "
@@ -2016,83 +2018,87 @@ enum vxge_hw_status vxge_reset_all_vpaths(struct vxgedev *vdev)
return status;
}
}
+ }
+
return status;
}
/* close vpaths */
void vxge_close_vpaths(struct vxgedev *vdev, int index)
{
+ struct vxge_vpath *vpath;
int i;
+
for (i = index; i < vdev->no_of_vpath; i++) {
- if (vdev->vpaths[i].handle && vdev->vpaths[i].is_open) {
- vxge_hw_vpath_close(vdev->vpaths[i].handle);
+ vpath = &vdev->vpaths[i];
+
+ if (vpath->handle && vpath->is_open) {
+ vxge_hw_vpath_close(vpath->handle);
vdev->stats.vpaths_open--;
}
- vdev->vpaths[i].is_open = 0;
- vdev->vpaths[i].handle = NULL;
+ vpath->is_open = 0;
+ vpath->handle = NULL;
}
}
/* open vpaths */
int vxge_open_vpaths(struct vxgedev *vdev)
{
+ struct vxge_hw_vpath_attr attr;
enum vxge_hw_status status;
- int i;
+ struct vxge_vpath *vpath;
u32 vp_id = 0;
- struct vxge_hw_vpath_attr attr;
+ int i;
for (i = 0; i < vdev->no_of_vpath; i++) {
- vxge_assert(vdev->vpaths[i].is_configured);
- attr.vp_id = vdev->vpaths[i].device_id;
+ vpath = &vdev->vpaths[i];
+
+ vxge_assert(vpath->is_configured);
+ attr.vp_id = vpath->device_id;
attr.fifo_attr.callback = vxge_xmit_compl;
attr.fifo_attr.txdl_term = vxge_tx_term;
attr.fifo_attr.per_txdl_space = sizeof(struct vxge_tx_priv);
- attr.fifo_attr.userdata = (void *)&vdev->vpaths[i].fifo;
+ attr.fifo_attr.userdata = &vpath->fifo;
attr.ring_attr.callback = vxge_rx_1b_compl;
attr.ring_attr.rxd_init = vxge_rx_initial_replenish;
attr.ring_attr.rxd_term = vxge_rx_term;
attr.ring_attr.per_rxd_space = sizeof(struct vxge_rx_priv);
- attr.ring_attr.userdata = (void *)&vdev->vpaths[i].ring;
+ attr.ring_attr.userdata = &vpath->ring;
- vdev->vpaths[i].ring.ndev = vdev->ndev;
- vdev->vpaths[i].ring.pdev = vdev->pdev;
- status = vxge_hw_vpath_open(vdev->devh, &attr,
- &(vdev->vpaths[i].handle));
+ vpath->ring.ndev = vdev->ndev;
+ vpath->ring.pdev = vdev->pdev;
+ status = vxge_hw_vpath_open(vdev->devh, &attr, &vpath->handle);
if (status == VXGE_HW_OK) {
- vdev->vpaths[i].fifo.handle =
+ vpath->fifo.handle =
(struct __vxge_hw_fifo *)attr.fifo_attr.userdata;
- vdev->vpaths[i].ring.handle =
+ vpath->ring.handle =
(struct __vxge_hw_ring *)attr.ring_attr.userdata;
- vdev->vpaths[i].fifo.tx_steering_type =
+ vpath->fifo.tx_steering_type =
vdev->config.tx_steering_type;
- vdev->vpaths[i].fifo.ndev = vdev->ndev;
- vdev->vpaths[i].fifo.pdev = vdev->pdev;
- vdev->vpaths[i].fifo.indicate_max_pkts =
+ vpath->fifo.ndev = vdev->ndev;
+ vpath->fifo.pdev = vdev->pdev;
+ vpath->fifo.indicate_max_pkts =
vdev->config.fifo_indicate_max_pkts;
- vdev->vpaths[i].ring.rx_vector_no = 0;
- vdev->vpaths[i].ring.rx_csum = vdev->rx_csum;
- vdev->vpaths[i].is_open = 1;
- vdev->vp_handles[i] = vdev->vpaths[i].handle;
- vdev->vpaths[i].ring.gro_enable =
- vdev->config.gro_enable;
- vdev->vpaths[i].ring.vlan_tag_strip =
- vdev->vlan_tag_strip;
+ vpath->ring.rx_vector_no = 0;
+ vpath->ring.rx_csum = vdev->rx_csum;
+ vpath->is_open = 1;
+ vdev->vp_handles[i] = vpath->handle;
+ vpath->ring.gro_enable = vdev->config.gro_enable;
+ vpath->ring.vlan_tag_strip = vdev->vlan_tag_strip;
vdev->stats.vpaths_open++;
} else {
vdev->stats.vpath_open_fail++;
vxge_debug_init(VXGE_ERR,
"%s: vpath: %d failed to open "
"with status: %d",
- vdev->ndev->name, vdev->vpaths[i].device_id,
+ vdev->ndev->name, vpath->device_id,
status);
vxge_close_vpaths(vdev, 0);
return -EPERM;
}
- vp_id =
- ((struct __vxge_hw_vpath_handle *)vdev->vpaths[i].handle)->
- vpath->vp_id;
+ vp_id = vpath->handle->vpath->vp_id;
vdev->vpaths_deployed |= vxge_mBIT(vp_id);
}
return VXGE_HW_OK;
@@ -2266,7 +2272,6 @@ start:
vdev->vxge_entries[j].in_use = 0;
ret = pci_enable_msix(vdev->pdev, vdev->entries, vdev->intr_cnt);
-
if (ret > 0) {
vxge_debug_init(VXGE_ERR,
"%s: MSI-X enable failed for %d vectors, ret: %d",
@@ -2312,17 +2317,16 @@ static int vxge_enable_msix(struct vxgedev *vdev)
ret = vxge_alloc_msix(vdev);
if (!ret) {
for (i = 0; i < vdev->no_of_vpath; i++) {
+ struct vxge_vpath *vpath = &vdev->vpaths[i];
- /* If fifo or ring are not enabled
- the MSIX vector for that should be set to 0
- Hence initializeing this array to all 0s.
- */
- vdev->vpaths[i].ring.rx_vector_no =
- (vdev->vpaths[i].device_id *
- VXGE_HW_VPATH_MSIX_ACTIVE) + 1;
+ /* If fifo or ring are not enabled, the MSIX vector for
+ * it should be set to 0.
+ */
+ vpath->ring.rx_vector_no = (vpath->device_id *
+ VXGE_HW_VPATH_MSIX_ACTIVE) + 1;
- vxge_hw_vpath_msix_set(vdev->vpaths[i].handle,
- tim_msix_id, VXGE_ALARM_MSIX_ID);
+ vxge_hw_vpath_msix_set(vpath->handle, tim_msix_id,
+ VXGE_ALARM_MSIX_ID);
}
}
@@ -2537,9 +2541,10 @@ static void vxge_poll_vp_reset(unsigned long data)
static void vxge_poll_vp_lockup(unsigned long data)
{
struct vxgedev *vdev = (struct vxgedev *)data;
- int i;
- struct vxge_ring *ring;
enum vxge_hw_status status = VXGE_HW_OK;
+ struct vxge_vpath *vpath;
+ struct vxge_ring *ring;
+ int i;
for (i = 0; i < vdev->no_of_vpath; i++) {
ring = &vdev->vpaths[i].ring;
@@ -2553,13 +2558,13 @@ static void vxge_poll_vp_lockup(unsigned long data)
/* schedule vpath reset */
if (!test_and_set_bit(i, &vdev->vp_reset)) {
+ vpath = &vdev->vpaths[i];
/* disable interrupts for this vpath */
vxge_vpath_intr_disable(vdev, i);
/* stop the queue for this vpath */
- vxge_stop_tx_queue(&vdev->vpaths[i].
- fifo);
+ vxge_stop_tx_queue(&vpath->fifo);
continue;
}
}
@@ -2588,6 +2593,7 @@ vxge_open(struct net_device *dev)
enum vxge_hw_status status;
struct vxgedev *vdev;
struct __vxge_hw_device *hldev;
+ struct vxge_vpath *vpath;
int ret = 0;
int i;
u64 val64, function_mode;
@@ -2626,15 +2632,17 @@ vxge_open(struct net_device *dev)
netif_napi_add(dev, &vdev->napi, vxge_poll_inta,
vdev->config.napi_weight);
napi_enable(&vdev->napi);
- for (i = 0; i < vdev->no_of_vpath; i++)
- vdev->vpaths[i].ring.napi_p = &vdev->napi;
+ for (i = 0; i < vdev->no_of_vpath; i++) {
+ vpath = &vdev->vpaths[i];
+ vpath->ring.napi_p = &vdev->napi;
+ }
} else {
for (i = 0; i < vdev->no_of_vpath; i++) {
- netif_napi_add(dev, &vdev->vpaths[i].ring.napi,
+ vpath = &vdev->vpaths[i];
+ netif_napi_add(dev, &vpath->ring.napi,
vxge_poll_msix, vdev->config.napi_weight);
- napi_enable(&vdev->vpaths[i].ring.napi);
- vdev->vpaths[i].ring.napi_p =
- &vdev->vpaths[i].ring.napi;
+ napi_enable(&vpath->ring.napi);
+ vpath->ring.napi_p = &vpath->ring.napi;
}
}
@@ -2651,9 +2659,10 @@ vxge_open(struct net_device *dev)
}
for (i = 0; i < vdev->no_of_vpath; i++) {
+ vpath = &vdev->vpaths[i];
+
/* set initial mtu before enabling the device */
- status = vxge_hw_vpath_mtu_set(vdev->vpaths[i].handle,
- vdev->mtu);
+ status = vxge_hw_vpath_mtu_set(vpath->handle, vdev->mtu);
if (status != VXGE_HW_OK) {
vxge_debug_init(VXGE_ERR,
"%s: fatal: can not set new MTU", dev->name);
@@ -2667,10 +2676,21 @@ vxge_open(struct net_device *dev)
"%s: MTU is %d", vdev->ndev->name, vdev->mtu);
VXGE_DEVICE_DEBUG_LEVEL_SET(VXGE_ERR, VXGE_COMPONENT_LL, vdev);
- /* Reprogram the DA table with populated mac addresses */
- for (i = 0; i < vdev->no_of_vpath; i++) {
- vxge_restore_vpath_mac_addr(&vdev->vpaths[i]);
- vxge_restore_vpath_vid_table(&vdev->vpaths[i]);
+ /* Restore the DA, VID table and also multicast and promiscuous mode
+ * states
+ */
+ if (vdev->all_multi_flg) {
+ for (i = 0; i < vdev->no_of_vpath; i++) {
+ vpath = &vdev->vpaths[i];
+ vxge_restore_vpath_mac_addr(vpath);
+ vxge_restore_vpath_vid_table(vpath);
+
+ status = vxge_hw_vpath_mcast_enable(vpath->handle);
+ if (status != VXGE_HW_OK)
+ vxge_debug_init(VXGE_ERR,
+ "%s:%d Enabling multicast failed",
+ __func__, __LINE__);
+ }
}
/* Enable vpath to sniff all unicast/multicast traffic that not
@@ -2699,14 +2719,14 @@ vxge_open(struct net_device *dev)
/* Enabling Bcast and mcast for all vpath */
for (i = 0; i < vdev->no_of_vpath; i++) {
- status = vxge_hw_vpath_bcast_enable(vdev->vpaths[i].handle);
+ vpath = &vdev->vpaths[i];
+ status = vxge_hw_vpath_bcast_enable(vpath->handle);
if (status != VXGE_HW_OK)
vxge_debug_init(VXGE_ERR,
"%s : Can not enable bcast for vpath "
"id %d", dev->name, i);
if (vdev->config.addr_learn_en) {
- status =
- vxge_hw_vpath_mcast_enable(vdev->vpaths[i].handle);
+ status = vxge_hw_vpath_mcast_enable(vpath->handle);
if (status != VXGE_HW_OK)
vxge_debug_init(VXGE_ERR,
"%s : Can not enable mcast for vpath "
@@ -2741,9 +2761,11 @@ vxge_open(struct net_device *dev)
smp_wmb();
for (i = 0; i < vdev->no_of_vpath; i++) {
- vxge_hw_vpath_enable(vdev->vpaths[i].handle);
+ vpath = &vdev->vpaths[i];
+
+ vxge_hw_vpath_enable(vpath->handle);
smp_wmb();
- vxge_hw_vpath_rx_doorbell_init(vdev->vpaths[i].handle);
+ vxge_hw_vpath_rx_doorbell_init(vpath->handle);
}
netif_tx_start_all_queues(vdev->ndev);
--
1.7.0.4
^ permalink raw reply related
* [PATCH 7/8] net: bridge: fix sign bug
From: Kulikov Vasiliy @ 2010-07-15 18:47 UTC (permalink / raw)
To: kernel-janitors
Cc: Stephen Hemminger, David S. Miller, Herbert Xu, YOSHIFUJI Hideaki,
Eric Dumazet, bridge, netdev
ipv6_skip_exthdr() can return error code that is below zero.
'offset' is unsigned, so it makes no sense.
ipv6_skip_exthdr() returns 'int' so we can painlessly change type of
offset to int.
Signed-off-by: Kulikov Vasiliy <segooon@gmail.com>
---
net/bridge/br_multicast.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index 27ae946..85afcda 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -1435,7 +1435,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
struct icmp6hdr *icmp6h;
u8 nexthdr;
unsigned len;
- unsigned offset;
+ int offset;
int err;
if (!pskb_may_pull(skb, sizeof(*ip6h)))
--
1.7.0.4
^ permalink raw reply related
* [PATCH 6/6] vxge: Version update
From: Jon Mason @ 2010-07-15 18:47 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Sreenivasa Honnur, Ramkrishna Vepa
Version update
Signed-off-by: Jon Mason <jon.mason@exar.com>
Signed-off-by: Sreenivasa Honnur <sreenivasa.honnur@exar.com>
Signed-off-by: Ramkrishna Vepa <ramkrishna.vepa@exar.com>
---
drivers/net/vxge/vxge-version.h | 5 ++---
1 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/net/vxge/vxge-version.h b/drivers/net/vxge/vxge-version.h
index 4008e6b..53fefe1 100644
--- a/drivers/net/vxge/vxge-version.h
+++ b/drivers/net/vxge/vxge-version.h
@@ -12,12 +12,11 @@
* Copyright(c) 2002-2010 Exar Corp.
******************************************************************************/
#ifndef VXGE_VERSION_H
-
#define VXGE_VERSION_H
#define VXGE_VERSION_MAJOR "2"
#define VXGE_VERSION_MINOR "0"
-#define VXGE_VERSION_FIX "8"
-#define VXGE_VERSION_BUILD "20182"
+#define VXGE_VERSION_FIX "9"
+#define VXGE_VERSION_BUILD "20840"
#define VXGE_VERSION_FOR "k"
#endif
--
1.7.0.4
^ permalink raw reply related
* [PATCH 5/6] vxge: Update maintainers information
From: Jon Mason @ 2010-07-15 18:47 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Sreenivasa Honnur, Ramkrishna Vepa
Update and correct maintainers information
Signed-off-by: Jon Mason <jon.mason@exar.com>
Signed-off-by: Sreenivasa Honnur <sreenivasa.honnur@exar.com>
Signed-off-by: Ramkrishna Vepa <ramkrishna.vepa@exar.com>
---
MAINTAINERS | 12 +++++++-----
1 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index bb6493b..c05b499 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3893,17 +3893,19 @@ L: netem@lists.linux-foundation.org
S: Maintained
F: net/sched/sch_netem.c
-NETERION (S2IO) 10GbE DRIVER (xframe/vxge)
-M: Ramkrishna Vepa <ram.vepa@neterion.com>
-M: Rastapur Santosh <santosh.rastapur@neterion.com>
-M: Sivakumar Subramani <sivakumar.subramani@neterion.com>
-M: Sreenivasa Honnur <sreenivasa.honnur@neterion.com>
+NETERION 10GbE DRIVERS (s2io/vxge)
+M: Ramkrishna Vepa <ramkrishna.vepa@exar.com>
+M: Sivakumar Subramani <sivakumar.subramani@exar.com>
+M: Sreenivasa Honnur <sreenivasa.honnur@exar.com>
+M: Jon Mason <jon.mason@exar.com>
L: netdev@vger.kernel.org
W: http://trac.neterion.com/cgi-bin/trac.cgi/wiki/Linux?Anonymous
W: http://trac.neterion.com/cgi-bin/trac.cgi/wiki/X3100Linux?Anonymous
S: Supported
F: Documentation/networking/s2io.txt
F: drivers/net/s2io*
+F: Documentation/networking/vxge.txt
+F: drivers/net/vxge/
NETFILTER/IPTABLES/IPCHAINS
P: Rusty Russell
--
1.7.0.4
^ permalink raw reply related
* [PATCH 4/6] vxge: Update copyright information
From: Jon Mason @ 2010-07-15 18:47 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Sreenivasa Honnur, Ramkrishna Vepa
Update copyright information to reflect the Exar purchase of Neterion
Signed-off-by: Jon Mason <jon.mason@exar.com>
Signed-off-by: Sreenivasa Honnur <sreenivasa.honnur@exar.com>
Signed-off-by: Ramkrishna Vepa <ramkrishna.vepa@exar.com>
---
drivers/net/s2io-regs.h | 2 +-
drivers/net/s2io.c | 4 ++--
drivers/net/s2io.h | 2 +-
drivers/net/vxge/Makefile | 2 +-
drivers/net/vxge/vxge-config.c | 4 ++--
drivers/net/vxge/vxge-config.h | 4 ++--
drivers/net/vxge/vxge-ethtool.c | 4 ++--
drivers/net/vxge/vxge-ethtool.h | 4 ++--
drivers/net/vxge/vxge-main.c | 6 +++---
drivers/net/vxge/vxge-main.h | 4 ++--
drivers/net/vxge/vxge-reg.h | 4 ++--
drivers/net/vxge/vxge-traffic.c | 4 ++--
drivers/net/vxge/vxge-traffic.h | 4 ++--
drivers/net/vxge/vxge-version.h | 4 ++--
14 files changed, 26 insertions(+), 26 deletions(-)
diff --git a/drivers/net/s2io-regs.h b/drivers/net/s2io-regs.h
index 416669f..3688325 100644
--- a/drivers/net/s2io-regs.h
+++ b/drivers/net/s2io-regs.h
@@ -1,6 +1,6 @@
/************************************************************************
* regs.h: A Linux PCI-X Ethernet driver for Neterion 10GbE Server NIC
- * Copyright(c) 2002-2007 Neterion Inc.
+ * Copyright(c) 2002-2010 Exar Corp.
* This software may be used and distributed according to the terms of
* the GNU General Public License (GPL), incorporated herein by reference.
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index d0af924..f9f9ed8 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -1,6 +1,6 @@
/************************************************************************
* s2io.c: A Linux PCI-X Ethernet driver for Neterion 10GbE Server NIC
- * Copyright(c) 2002-2007 Neterion Inc.
+ * Copyright(c) 2002-2010 Exar Corp.
*
* This software may be used and distributed according to the terms of
* the GNU General Public License (GPL), incorporated herein by reference.
@@ -8199,7 +8199,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
goto register_failed;
}
s2io_vpd_read(sp);
- DBG_PRINT(ERR_DBG, "Copyright(c) 2002-2007 Neterion Inc.\n");
+ DBG_PRINT(ERR_DBG, "Copyright(c) 2002-2010 Exar Corp.\n");
DBG_PRINT(ERR_DBG, "%s: Neterion %s (rev %d)\n", dev->name,
sp->product_name, pdev->revision);
DBG_PRINT(ERR_DBG, "%s: Driver version %s\n", dev->name,
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
index 5e52c75..3645fb3 100644
--- a/drivers/net/s2io.h
+++ b/drivers/net/s2io.h
@@ -1,6 +1,6 @@
/************************************************************************
* s2io.h: A Linux PCI-X Ethernet driver for Neterion 10GbE Server NIC
- * Copyright(c) 2002-2007 Neterion Inc.
+ * Copyright(c) 2002-2010 Exar Corp.
* This software may be used and distributed according to the terms of
* the GNU General Public License (GPL), incorporated herein by reference.
diff --git a/drivers/net/vxge/Makefile b/drivers/net/vxge/Makefile
index 8992ca2..b625e2c 100644
--- a/drivers/net/vxge/Makefile
+++ b/drivers/net/vxge/Makefile
@@ -1,5 +1,5 @@
#
-# Makefile for Neterion Inc's X3100 Series 10 GbE PCIe # I/O
+# Makefile for Exar Corp's X3100 Series 10 GbE PCIe I/O
# Virtualized Server Adapter linux driver
obj-$(CONFIG_VXGE) += vxge.o
diff --git a/drivers/net/vxge/vxge-config.c b/drivers/net/vxge/vxge-config.c
index 297f0d2..0e6db59 100644
--- a/drivers/net/vxge/vxge-config.c
+++ b/drivers/net/vxge/vxge-config.c
@@ -7,9 +7,9 @@
* system is licensed under the GPL.
* See the file COPYING in this distribution for more information.
*
- * vxge-config.c: Driver for Neterion Inc's X3100 Series 10GbE PCIe I/O
+ * vxge-config.c: Driver for Exar Corp's X3100 Series 10GbE PCIe I/O
* Virtualized Server Adapter.
- * Copyright(c) 2002-2009 Neterion Inc.
+ * Copyright(c) 2002-2010 Exar Corp.
******************************************************************************/
#include <linux/vmalloc.h>
#include <linux/etherdevice.h>
diff --git a/drivers/net/vxge/vxge-config.h b/drivers/net/vxge/vxge-config.h
index 4ae2625..1a94343 100644
--- a/drivers/net/vxge/vxge-config.h
+++ b/drivers/net/vxge/vxge-config.h
@@ -7,9 +7,9 @@
* system is licensed under the GPL.
* See the file COPYING in this distribution for more information.
*
- * vxge-config.h: Driver for Neterion Inc's X3100 Series 10GbE PCIe I/O
+ * vxge-config.h: Driver for Exar Corp's X3100 Series 10GbE PCIe I/O
* Virtualized Server Adapter.
- * Copyright(c) 2002-2009 Neterion Inc.
+ * Copyright(c) 2002-2010 Exar Corp.
******************************************************************************/
#ifndef VXGE_CONFIG_H
#define VXGE_CONFIG_H
diff --git a/drivers/net/vxge/vxge-ethtool.c b/drivers/net/vxge/vxge-ethtool.c
index cadef85..05679e3 100644
--- a/drivers/net/vxge/vxge-ethtool.c
+++ b/drivers/net/vxge/vxge-ethtool.c
@@ -7,9 +7,9 @@
* system is licensed under the GPL.
* See the file COPYING in this distribution for more information.
*
- * vxge-ethtool.c: Driver for Neterion Inc's X3100 Series 10GbE PCIe I/O
+ * vxge-ethtool.c: Driver for Exar Corp's X3100 Series 10GbE PCIe I/O
* Virtualized Server Adapter.
- * Copyright(c) 2002-2009 Neterion Inc.
+ * Copyright(c) 2002-2010 Exar Corp.
******************************************************************************/
#include<linux/ethtool.h>
#include <linux/slab.h>
diff --git a/drivers/net/vxge/vxge-ethtool.h b/drivers/net/vxge/vxge-ethtool.h
index 1c3df0a..6cf3044 100644
--- a/drivers/net/vxge/vxge-ethtool.h
+++ b/drivers/net/vxge/vxge-ethtool.h
@@ -7,9 +7,9 @@
* system is licensed under the GPL.
* See the file COPYING in this distribution for more information.
*
- * vxge-ethtool.h: Driver for Neterion Inc's X3100 Series 10GbE PCIe I/O
+ * vxge-ethtool.h: Driver for Exar Corp's X3100 Series 10GbE PCIe I/O
* Virtualized Server Adapter.
- * Copyright(c) 2002-2009 Neterion Inc.
+ * Copyright(c) 2002-2010 Exar Corp.
******************************************************************************/
#ifndef _VXGE_ETHTOOL_H
#define _VXGE_ETHTOOL_H
diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c
index 48f1732..94d87e8 100644
--- a/drivers/net/vxge/vxge-main.c
+++ b/drivers/net/vxge/vxge-main.c
@@ -7,9 +7,9 @@
* system is licensed under the GPL.
* See the file COPYING in this distribution for more information.
*
-* vxge-main.c: Driver for Neterion Inc's X3100 Series 10GbE PCIe I/O
+* vxge-main.c: Driver for Exar Corp's X3100 Series 10GbE PCIe I/O
* Virtualized Server Adapter.
-* Copyright(c) 2002-2009 Neterion Inc.
+* Copyright(c) 2002-2010 Exar Corp.
*
* The module loadable parameters that are supported by the driver and a brief
* explanation of all the variables:
@@ -4433,7 +4433,7 @@ vxge_starter(void)
char version[32];
snprintf(version, 32, "%s", DRV_VERSION);
- printk(KERN_INFO "%s: Copyright(c) 2002-2009 Neterion Inc\n",
+ printk(KERN_INFO "%s: Copyright(c) 2002-2010 Exar Corp.\n",
VXGE_DRIVER_NAME);
printk(KERN_INFO "%s: Driver version: %s\n",
VXGE_DRIVER_NAME, version);
diff --git a/drivers/net/vxge/vxge-main.h b/drivers/net/vxge/vxge-main.h
index 5982396..2e3b064 100644
--- a/drivers/net/vxge/vxge-main.h
+++ b/drivers/net/vxge/vxge-main.h
@@ -7,9 +7,9 @@
* system is licensed under the GPL.
* See the file COPYING in this distribution for more information.
*
- * vxge-main.h: Driver for Neterion Inc's X3100 Series 10GbE PCIe I/O
+ * vxge-main.h: Driver for Exar Corp's X3100 Series 10GbE PCIe I/O
* Virtualized Server Adapter.
- * Copyright(c) 2002-2009 Neterion Inc.
+ * Copyright(c) 2002-2010 Exar Corp.
******************************************************************************/
#ifndef VXGE_MAIN_H
#define VXGE_MAIN_H
diff --git a/drivers/net/vxge/vxge-reg.h b/drivers/net/vxge/vxge-reg.h
index 9a0cf8e..3dd5c96 100644
--- a/drivers/net/vxge/vxge-reg.h
+++ b/drivers/net/vxge/vxge-reg.h
@@ -7,9 +7,9 @@
* system is licensed under the GPL.
* See the file COPYING in this distribution for more information.
*
- * vxge-reg.h: Driver for Neterion Inc's X3100 Series 10GbE PCIe I/O Virtualized
+ * vxge-reg.h: Driver for Exar Corp's X3100 Series 10GbE PCIe I/O Virtualized
* Server Adapter.
- * Copyright(c) 2002-2009 Neterion Inc.
+ * Copyright(c) 2002-2010 Exar Corp.
******************************************************************************/
#ifndef VXGE_REG_H
#define VXGE_REG_H
diff --git a/drivers/net/vxge/vxge-traffic.c b/drivers/net/vxge/vxge-traffic.c
index 1a70783..cedf08f 100644
--- a/drivers/net/vxge/vxge-traffic.c
+++ b/drivers/net/vxge/vxge-traffic.c
@@ -7,9 +7,9 @@
* system is licensed under the GPL.
* See the file COPYING in this distribution for more information.
*
- * vxge-traffic.c: Driver for Neterion Inc's X3100 Series 10GbE PCIe I/O
+ * vxge-traffic.c: Driver for Exar Corp's X3100 Series 10GbE PCIe I/O
* Virtualized Server Adapter.
- * Copyright(c) 2002-2009 Neterion Inc.
+ * Copyright(c) 2002-2010 Exar Corp.
******************************************************************************/
#include <linux/etherdevice.h>
diff --git a/drivers/net/vxge/vxge-traffic.h b/drivers/net/vxge/vxge-traffic.h
index c252f3d..6fa07d1 100644
--- a/drivers/net/vxge/vxge-traffic.h
+++ b/drivers/net/vxge/vxge-traffic.h
@@ -7,9 +7,9 @@
* system is licensed under the GPL.
* See the file COPYING in this distribution for more information.
*
- * vxge-traffic.h: Driver for Neterion Inc's X3100 Series 10GbE PCIe I/O
+ * vxge-traffic.h: Driver for Exar Corp's X3100 Series 10GbE PCIe I/O
* Virtualized Server Adapter.
- * Copyright(c) 2002-2009 Neterion Inc.
+ * Copyright(c) 2002-2010 Exar Corp.
******************************************************************************/
#ifndef VXGE_TRAFFIC_H
#define VXGE_TRAFFIC_H
diff --git a/drivers/net/vxge/vxge-version.h b/drivers/net/vxge/vxge-version.h
index 5da7ab1..4008e6b 100644
--- a/drivers/net/vxge/vxge-version.h
+++ b/drivers/net/vxge/vxge-version.h
@@ -7,9 +7,9 @@
* system is licensed under the GPL.
* See the file COPYING in this distribution for more information.
*
- * vxge-version.h: Driver for Neterion Inc's X3100 Series 10GbE PCIe I/O
+ * vxge-version.h: Driver for Exar Corp's X3100 Series 10GbE PCIe I/O
* Virtualized Server Adapter.
- * Copyright(c) 2002-2009 Neterion Inc.
+ * Copyright(c) 2002-2010 Exar Corp.
******************************************************************************/
#ifndef VXGE_VERSION_H
--
1.7.0.4
^ permalink raw reply related
* [PATCH 3/6] vxge: NETIF_F_LLTX removal
From: Jon Mason @ 2010-07-15 18:47 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Ramkrishna Vepa
NETIF_F_LLTX and it's usage of local transmit locks are depricated in
favor of using the netdev queue's transmit lock. Remove the local
lock and all references to it, and use the netdev queue transmit lock
in the transmit completion handler.
Signed-off-by: Jon Mason <jon.mason@exar.com>
Signed-off-by: Ramkrishna Vepa <ramkrishna.vepa@exar.com>
---
drivers/net/vxge/vxge-main.c | 149 +++++++++------------------------------
drivers/net/vxge/vxge-main.h | 15 +---
drivers/net/vxge/vxge-traffic.c | 4 +-
3 files changed, 39 insertions(+), 129 deletions(-)
diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c
index 66d914c..48f1732 100644
--- a/drivers/net/vxge/vxge-main.c
+++ b/drivers/net/vxge/vxge-main.c
@@ -87,7 +87,6 @@ static inline int is_vxge_card_up(struct vxgedev *vdev)
static inline void VXGE_COMPLETE_VPATH_TX(struct vxge_fifo *fifo)
{
- unsigned long flags = 0;
struct sk_buff **skb_ptr = NULL;
struct sk_buff **temp;
#define NR_SKB_COMPLETED 128
@@ -98,15 +97,16 @@ static inline void VXGE_COMPLETE_VPATH_TX(struct vxge_fifo *fifo)
more = 0;
skb_ptr = completed;
- if (spin_trylock_irqsave(&fifo->tx_lock, flags)) {
+ if (__netif_tx_trylock(fifo->txq)) {
vxge_hw_vpath_poll_tx(fifo->handle, &skb_ptr,
NR_SKB_COMPLETED, &more);
- spin_unlock_irqrestore(&fifo->tx_lock, flags);
+ __netif_tx_unlock(fifo->txq);
}
+
/* free SKBs */
for (temp = completed; temp != skb_ptr; temp++)
dev_kfree_skb_irq(*temp);
- } while (more) ;
+ } while (more);
}
static inline void VXGE_COMPLETE_ALL_TX(struct vxgedev *vdev)
@@ -131,53 +131,6 @@ static inline void VXGE_COMPLETE_ALL_RX(struct vxgedev *vdev)
}
/*
- * MultiQ manipulation helper functions
- */
-static inline int vxge_netif_queue_stopped(struct vxge_fifo *fifo)
-{
- struct net_device *dev = fifo->ndev;
- struct netdev_queue *txq = NULL;
- int vpath_no = fifo->driver_id;
- int ret = 0;
-
- if (fifo->tx_steering_type)
- txq = netdev_get_tx_queue(dev, vpath_no);
- else
- txq = netdev_get_tx_queue(dev, 0);
-
- ret = netif_tx_queue_stopped(txq);
- return ret;
-}
-
-void vxge_stop_tx_queue(struct vxge_fifo *fifo)
-{
- struct net_device *dev = fifo->ndev;
- struct netdev_queue *txq = NULL;
-
- if (fifo->tx_steering_type)
- txq = netdev_get_tx_queue(dev, fifo->driver_id);
- else
- txq = netdev_get_tx_queue(dev, 0);
-
- netif_tx_stop_queue(txq);
-}
-
-void vxge_wake_tx_queue(struct vxge_fifo *fifo)
-{
- struct net_device *dev = fifo->ndev;
- struct netdev_queue *txq = NULL;
- int vpath_no = fifo->driver_id;
-
- if (fifo->tx_steering_type)
- txq = netdev_get_tx_queue(dev, vpath_no);
- else
- txq = netdev_get_tx_queue(dev, 0);
-
- if (netif_tx_queue_stopped(txq))
- netif_tx_wake_queue(txq);
-}
-
-/*
* vxge_callback_link_up
*
* This function is called during interrupt context to notify link up state
@@ -650,7 +603,8 @@ vxge_xmit_compl(struct __vxge_hw_fifo *fifo_hw, void *dtr,
&dtr, &t_code) == VXGE_HW_OK);
*skb_ptr = done_skb;
- vxge_wake_tx_queue(fifo);
+ if (netif_tx_queue_stopped(fifo->txq))
+ netif_tx_wake_queue(fifo->txq);
vxge_debug_entryexit(VXGE_TRACE,
"%s: %s:%d Exiting...",
@@ -659,8 +613,7 @@ vxge_xmit_compl(struct __vxge_hw_fifo *fifo_hw, void *dtr,
}
/* select a vpath to transmit the packet */
-static u32 vxge_get_vpath_no(struct vxgedev *vdev, struct sk_buff *skb,
- int *do_lock)
+static u32 vxge_get_vpath_no(struct vxgedev *vdev, struct sk_buff *skb)
{
u16 queue_len, counter = 0;
if (skb->protocol == htons(ETH_P_IP)) {
@@ -679,12 +632,6 @@ static u32 vxge_get_vpath_no(struct vxgedev *vdev, struct sk_buff *skb,
vdev->vpath_selector[queue_len - 1];
if (counter >= queue_len)
counter = queue_len - 1;
-
- if (ip->protocol == IPPROTO_UDP) {
-#ifdef NETIF_F_LLTX
- *do_lock = 0;
-#endif
- }
}
}
return counter;
@@ -781,8 +728,6 @@ static int vxge_learn_mac(struct vxgedev *vdev, u8 *mac_header)
*
* This function is the Tx entry point of the driver. Neterion NIC supports
* certain protocol assist features on Tx side, namely CSO, S/G, LSO.
- * NOTE: when device cant queue the pkt, just the trans_start variable will
- * not be upadted.
*/
static netdev_tx_t
vxge_xmit(struct sk_buff *skb, struct net_device *dev)
@@ -799,9 +744,7 @@ vxge_xmit(struct sk_buff *skb, struct net_device *dev)
struct vxge_tx_priv *txdl_priv = NULL;
struct __vxge_hw_fifo *fifo_hw;
int offload_type;
- unsigned long flags = 0;
int vpath_no = 0;
- int do_spin_tx_lock = 1;
vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d",
dev->name, __func__, __LINE__);
@@ -837,7 +780,7 @@ vxge_xmit(struct sk_buff *skb, struct net_device *dev)
if (vdev->config.tx_steering_type == TX_MULTIQ_STEERING)
vpath_no = skb_get_queue_mapping(skb);
else if (vdev->config.tx_steering_type == TX_PORT_STEERING)
- vpath_no = vxge_get_vpath_no(vdev, skb, &do_spin_tx_lock);
+ vpath_no = vxge_get_vpath_no(vdev, skb);
vxge_debug_tx(VXGE_TRACE, "%s: vpath_no= %d", dev->name, vpath_no);
@@ -847,40 +790,29 @@ vxge_xmit(struct sk_buff *skb, struct net_device *dev)
fifo = &vdev->vpaths[vpath_no].fifo;
fifo_hw = fifo->handle;
- if (do_spin_tx_lock)
- spin_lock_irqsave(&fifo->tx_lock, flags);
- else {
- if (unlikely(!spin_trylock_irqsave(&fifo->tx_lock, flags)))
- return NETDEV_TX_LOCKED;
- }
-
- if (vxge_netif_queue_stopped(fifo)) {
- spin_unlock_irqrestore(&fifo->tx_lock, flags);
+ if (netif_tx_queue_stopped(fifo->txq))
return NETDEV_TX_BUSY;
- }
avail = vxge_hw_fifo_free_txdl_count_get(fifo_hw);
if (avail == 0) {
vxge_debug_tx(VXGE_ERR,
"%s: No free TXDs available", dev->name);
fifo->stats.txd_not_free++;
- vxge_stop_tx_queue(fifo);
- goto _exit2;
+ goto _exit0;
}
/* Last TXD? Stop tx queue to avoid dropping packets. TX
* completion will resume the queue.
*/
if (avail == 1)
- vxge_stop_tx_queue(fifo);
+ netif_tx_stop_queue(fifo->txq);
status = vxge_hw_fifo_txdl_reserve(fifo_hw, &dtr, &dtr_priv);
if (unlikely(status != VXGE_HW_OK)) {
vxge_debug_tx(VXGE_ERR,
"%s: Out of descriptors .", dev->name);
fifo->stats.txd_out_of_desc++;
- vxge_stop_tx_queue(fifo);
- goto _exit2;
+ goto _exit0;
}
vxge_debug_tx(VXGE_TRACE,
@@ -900,9 +832,8 @@ vxge_xmit(struct sk_buff *skb, struct net_device *dev)
if (unlikely(pci_dma_mapping_error(fifo->pdev, dma_pointer))) {
vxge_hw_fifo_txdl_free(fifo_hw, dtr);
- vxge_stop_tx_queue(fifo);
fifo->stats.pci_map_fail++;
- goto _exit2;
+ goto _exit0;
}
txdl_priv = vxge_hw_fifo_txdl_private_get(dtr);
@@ -925,13 +856,12 @@ vxge_xmit(struct sk_buff *skb, struct net_device *dev)
if (!frag->size)
continue;
- dma_pointer =
- (u64)pci_map_page(fifo->pdev, frag->page,
+ dma_pointer = (u64) pci_map_page(fifo->pdev, frag->page,
frag->page_offset, frag->size,
PCI_DMA_TODEVICE);
if (unlikely(pci_dma_mapping_error(fifo->pdev, dma_pointer)))
- goto _exit0;
+ goto _exit2;
vxge_debug_tx(VXGE_TRACE,
"%s: %s:%d frag = %d dma_pointer = 0x%llx",
dev->name, __func__, __LINE__, i,
@@ -946,11 +876,9 @@ vxge_xmit(struct sk_buff *skb, struct net_device *dev)
offload_type = vxge_offload_type(skb);
if (offload_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) {
-
int mss = vxge_tcp_mss(skb);
if (mss) {
- vxge_debug_tx(VXGE_TRACE,
- "%s: %s:%d mss = %d",
+ vxge_debug_tx(VXGE_TRACE, "%s: %s:%d mss = %d",
dev->name, __func__, __LINE__, mss);
vxge_hw_fifo_txdl_mss_set(dtr, mss);
} else {
@@ -968,19 +896,13 @@ vxge_xmit(struct sk_buff *skb, struct net_device *dev)
VXGE_HW_FIFO_TXD_TX_CKO_UDP_EN);
vxge_hw_fifo_txdl_post(fifo_hw, dtr);
-#ifdef NETIF_F_LLTX
- dev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */
-#endif
- spin_unlock_irqrestore(&fifo->tx_lock, flags);
- VXGE_COMPLETE_VPATH_TX(fifo);
vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d Exiting...",
dev->name, __func__, __LINE__);
return NETDEV_TX_OK;
-_exit0:
+_exit2:
vxge_debug_tx(VXGE_TRACE, "%s: pci_map_page failed", dev->name);
-
_exit1:
j = 0;
frag = &skb_shinfo(skb)->frags[0];
@@ -995,10 +917,9 @@ _exit1:
}
vxge_hw_fifo_txdl_free(fifo_hw, dtr);
-_exit2:
+_exit0:
+ netif_tx_stop_queue(fifo->txq);
dev_kfree_skb(skb);
- spin_unlock_irqrestore(&fifo->tx_lock, flags);
- VXGE_COMPLETE_VPATH_TX(fifo);
return NETDEV_TX_OK;
}
@@ -1448,7 +1369,8 @@ static int vxge_reset_vpath(struct vxgedev *vdev, int vp_id)
clear_bit(vp_id, &vdev->vp_reset);
/* Start the vpath queue */
- vxge_wake_tx_queue(&vpath->fifo);
+ if (netif_tx_queue_stopped(vpath->fifo.txq))
+ netif_tx_wake_queue(vpath->fifo.txq);
return ret;
}
@@ -2078,6 +2000,12 @@ int vxge_open_vpaths(struct vxgedev *vdev)
vdev->config.tx_steering_type;
vpath->fifo.ndev = vdev->ndev;
vpath->fifo.pdev = vdev->pdev;
+ if (vdev->config.tx_steering_type)
+ vpath->fifo.txq =
+ netdev_get_tx_queue(vdev->ndev, i);
+ else
+ vpath->fifo.txq =
+ netdev_get_tx_queue(vdev->ndev, 0);
vpath->fifo.indicate_max_pkts =
vdev->config.fifo_indicate_max_pkts;
vpath->ring.rx_vector_no = 0;
@@ -2564,7 +2492,7 @@ static void vxge_poll_vp_lockup(unsigned long data)
vxge_vpath_intr_disable(vdev, i);
/* stop the queue for this vpath */
- vxge_stop_tx_queue(&vpath->fifo);
+ netif_tx_stop_queue(vpath->fifo.txq);
continue;
}
}
@@ -2627,7 +2555,6 @@ vxge_open(struct net_device *dev)
goto out1;
}
-
if (vdev->config.intr_type != MSI_X) {
netif_napi_add(dev, &vdev->napi, vxge_poll_inta,
vdev->config.napi_weight);
@@ -3200,7 +3127,7 @@ int __devinit vxge_device_register(struct __vxge_hw_device *hldev,
struct net_device *ndev;
enum vxge_hw_status status = VXGE_HW_OK;
struct vxgedev *vdev;
- int i, ret = 0, no_of_queue = 1;
+ int ret = 0, no_of_queue = 1;
u64 stat;
*vdev_out = NULL;
@@ -3273,13 +3200,6 @@ int __devinit vxge_device_register(struct __vxge_hw_device *hldev,
if (vdev->config.gro_enable)
ndev->features |= NETIF_F_GRO;
-#ifdef NETIF_F_LLTX
- ndev->features |= NETIF_F_LLTX;
-#endif
-
- for (i = 0; i < no_of_vpath; i++)
- spin_lock_init(&vdev->vpaths[i].fifo.tx_lock);
-
if (register_netdev(ndev)) {
vxge_debug_init(vxge_hw_device_trace_level_get(hldev),
"%s: %s : device registration failed!",
@@ -3379,6 +3299,7 @@ vxge_callback_crit_err(struct __vxge_hw_device *hldev,
{
struct net_device *dev = hldev->ndev;
struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+ struct vxge_vpath *vpath = NULL;
int vpath_idx;
vxge_debug_entryexit(vdev->level_trace,
@@ -3389,9 +3310,11 @@ vxge_callback_crit_err(struct __vxge_hw_device *hldev,
*/
vdev->cric_err_event = type;
- for (vpath_idx = 0; vpath_idx < vdev->no_of_vpath; vpath_idx++)
- if (vdev->vpaths[vpath_idx].device_id == vp_id)
+ for (vpath_idx = 0; vpath_idx < vdev->no_of_vpath; vpath_idx++) {
+ vpath = &vdev->vpaths[vpath_idx];
+ if (vpath->device_id == vp_id)
break;
+ }
if (!test_bit(__VXGE_STATE_RESET_CARD, &vdev->state)) {
if (type == VXGE_HW_EVENT_SLOT_FREEZE) {
@@ -3428,8 +3351,7 @@ vxge_callback_crit_err(struct __vxge_hw_device *hldev,
vxge_vpath_intr_disable(vdev, vpath_idx);
/* stop the queue for this vpath */
- vxge_stop_tx_queue(&vdev->vpaths[vpath_idx].
- fifo);
+ netif_tx_stop_queue(vpath->fifo.txq);
}
}
}
@@ -4274,7 +4196,6 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
vdev->vpaths[j].is_configured = 1;
vdev->vpaths[j].device_id = i;
- vdev->vpaths[j].fifo.driver_id = j;
vdev->vpaths[j].ring.driver_id = j;
vdev->vpaths[j].vdev = vdev;
vdev->vpaths[j].max_mac_addr_cnt = max_mac_vpath;
diff --git a/drivers/net/vxge/vxge-main.h b/drivers/net/vxge/vxge-main.h
index a384582..5982396 100644
--- a/drivers/net/vxge/vxge-main.h
+++ b/drivers/net/vxge/vxge-main.h
@@ -217,17 +217,13 @@ struct vxge_fifo_stats {
};
struct vxge_fifo {
- struct net_device *ndev;
- struct pci_dev *pdev;
+ struct net_device *ndev;
+ struct pci_dev *pdev;
struct __vxge_hw_fifo *handle;
+ struct netdev_queue *txq;
- /* The vpath id maintained in the driver -
- * 0 to 'maximum_vpaths_in_function - 1'
- */
- int driver_id;
int tx_steering_type;
int indicate_max_pkts;
- spinlock_t tx_lock;
/* Tx stats */
struct vxge_fifo_stats stats;
@@ -275,7 +271,6 @@ struct vxge_ring {
} ____cacheline_aligned;
struct vxge_vpath {
-
struct vxge_fifo fifo;
struct vxge_ring ring;
@@ -443,10 +438,6 @@ int vxge_open_vpaths(struct vxgedev *vdev);
enum vxge_hw_status vxge_reset_all_vpaths(struct vxgedev *vdev);
-void vxge_stop_tx_queue(struct vxge_fifo *fifo);
-
-void vxge_wake_tx_queue(struct vxge_fifo *fifo);
-
enum vxge_hw_status vxge_add_mac_addr(struct vxgedev *vdev,
struct macInfo *mac);
diff --git a/drivers/net/vxge/vxge-traffic.c b/drivers/net/vxge/vxge-traffic.c
index 6cc1dd7..1a70783 100644
--- a/drivers/net/vxge/vxge-traffic.c
+++ b/drivers/net/vxge/vxge-traffic.c
@@ -2466,14 +2466,12 @@ enum vxge_hw_status vxge_hw_vpath_poll_rx(struct __vxge_hw_ring *ring)
* the same.
* @fifo: Handle to the fifo object used for non offload send
*
- * The function polls the Tx for the completed descriptors and calls
+ * The function polls the Tx for the completed descriptors and calls
* the driver via supplied completion callback.
*
* Returns: VXGE_HW_OK, if the polling is completed successful.
* VXGE_HW_COMPLETIONS_REMAIN: There are still more completed
* descriptors available which are yet to be processed.
- *
- * See also: vxge_hw_vpath_poll_tx().
*/
enum vxge_hw_status vxge_hw_vpath_poll_tx(struct __vxge_hw_fifo *fifo,
struct sk_buff ***skb_ptr, int nr_skb,
--
1.7.0.4
^ permalink raw reply related
* [PATCH 1/6] vxge: Remove queue_state references
From: Jon Mason @ 2010-07-15 18:47 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Sreenivasa Honnur, Ramkrishna Vepa
Remove queue_state references, as they are no longer necessary.
Also, The driver needs to start/stop the queue regardless of which type
of steering is enabled. Remove checks for TX_MULTIQ_STEERING only and
start/stop for all steering types.
Signed-off-by: Jon Mason <jon.mason@exar.com>
Signed-off-by: Sreenivasa Honnur <sreenivasa.honnur@exar.com>
Signed-off-by: Ramkrishna Vepa <ramkrishna.vepa@exar.com>
---
drivers/net/vxge/vxge-main.c | 118 +++++++++++++++---------------------------
drivers/net/vxge/vxge-main.h | 10 +---
2 files changed, 42 insertions(+), 86 deletions(-)
diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c
index ed17865..e78703d 100644
--- a/drivers/net/vxge/vxge-main.c
+++ b/drivers/net/vxge/vxge-main.c
@@ -133,75 +133,48 @@ static inline void VXGE_COMPLETE_ALL_RX(struct vxgedev *vdev)
/*
* MultiQ manipulation helper functions
*/
-void vxge_stop_all_tx_queue(struct vxgedev *vdev)
+static inline int vxge_netif_queue_stopped(struct vxge_fifo *fifo)
{
- int i;
- struct net_device *dev = vdev->ndev;
+ struct net_device *dev = fifo->ndev;
+ struct netdev_queue *txq = NULL;
+ int vpath_no = fifo->driver_id;
+ int ret = 0;
- if (vdev->config.tx_steering_type != TX_MULTIQ_STEERING) {
- for (i = 0; i < vdev->no_of_vpath; i++)
- vdev->vpaths[i].fifo.queue_state = VPATH_QUEUE_STOP;
- }
- netif_tx_stop_all_queues(dev);
+ if (fifo->tx_steering_type)
+ txq = netdev_get_tx_queue(dev, vpath_no);
+ else
+ txq = netdev_get_tx_queue(dev, 0);
+
+ ret = netif_tx_queue_stopped(txq);
+ return ret;
}
void vxge_stop_tx_queue(struct vxge_fifo *fifo)
{
struct net_device *dev = fifo->ndev;
-
struct netdev_queue *txq = NULL;
- if (fifo->tx_steering_type == TX_MULTIQ_STEERING)
+
+ if (fifo->tx_steering_type)
txq = netdev_get_tx_queue(dev, fifo->driver_id);
- else {
+ else
txq = netdev_get_tx_queue(dev, 0);
- fifo->queue_state = VPATH_QUEUE_STOP;
- }
netif_tx_stop_queue(txq);
}
-void vxge_start_all_tx_queue(struct vxgedev *vdev)
-{
- int i;
- struct net_device *dev = vdev->ndev;
-
- if (vdev->config.tx_steering_type != TX_MULTIQ_STEERING) {
- for (i = 0; i < vdev->no_of_vpath; i++)
- vdev->vpaths[i].fifo.queue_state = VPATH_QUEUE_START;
- }
- netif_tx_start_all_queues(dev);
-}
-
-static void vxge_wake_all_tx_queue(struct vxgedev *vdev)
-{
- int i;
- struct net_device *dev = vdev->ndev;
-
- if (vdev->config.tx_steering_type != TX_MULTIQ_STEERING) {
- for (i = 0; i < vdev->no_of_vpath; i++)
- vdev->vpaths[i].fifo.queue_state = VPATH_QUEUE_START;
- }
- netif_tx_wake_all_queues(dev);
-}
-
-void vxge_wake_tx_queue(struct vxge_fifo *fifo, struct sk_buff *skb)
+void vxge_wake_tx_queue(struct vxge_fifo *fifo)
{
struct net_device *dev = fifo->ndev;
-
- int vpath_no = fifo->driver_id;
struct netdev_queue *txq = NULL;
- if (fifo->tx_steering_type == TX_MULTIQ_STEERING) {
+ int vpath_no = fifo->driver_id;
+
+ if (fifo->tx_steering_type)
txq = netdev_get_tx_queue(dev, vpath_no);
- if (netif_tx_queue_stopped(txq))
- netif_tx_wake_queue(txq);
- } else {
+ else
txq = netdev_get_tx_queue(dev, 0);
- if (fifo->queue_state == VPATH_QUEUE_STOP)
- if (netif_tx_queue_stopped(txq)) {
- fifo->queue_state = VPATH_QUEUE_START;
- netif_tx_wake_queue(txq);
- }
- }
+
+ if (netif_tx_queue_stopped(txq))
+ netif_tx_wake_queue(txq);
}
/*
@@ -222,7 +195,7 @@ vxge_callback_link_up(struct __vxge_hw_device *hldev)
vdev->stats.link_up++;
netif_carrier_on(vdev->ndev);
- vxge_wake_all_tx_queue(vdev);
+ netif_tx_wake_all_queues(vdev->ndev);
vxge_debug_entryexit(VXGE_TRACE,
"%s: %s:%d Exiting...", vdev->ndev->name, __func__, __LINE__);
@@ -246,7 +219,7 @@ vxge_callback_link_down(struct __vxge_hw_device *hldev)
vdev->stats.link_down++;
netif_carrier_off(vdev->ndev);
- vxge_stop_all_tx_queue(vdev);
+ netif_tx_stop_all_queues(vdev->ndev);
vxge_debug_entryexit(VXGE_TRACE,
"%s: %s:%d Exiting...", vdev->ndev->name, __func__, __LINE__);
@@ -677,7 +650,7 @@ vxge_xmit_compl(struct __vxge_hw_fifo *fifo_hw, void *dtr,
&dtr, &t_code) == VXGE_HW_OK);
*skb_ptr = done_skb;
- vxge_wake_tx_queue(fifo, skb);
+ vxge_wake_tx_queue(fifo);
vxge_debug_entryexit(VXGE_TRACE,
"%s: %s:%d Exiting...",
@@ -881,17 +854,11 @@ vxge_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_LOCKED;
}
- if (vdev->config.tx_steering_type == TX_MULTIQ_STEERING) {
- if (netif_subqueue_stopped(dev, skb)) {
- spin_unlock_irqrestore(&fifo->tx_lock, flags);
- return NETDEV_TX_BUSY;
- }
- } else if (unlikely(fifo->queue_state == VPATH_QUEUE_STOP)) {
- if (netif_queue_stopped(dev)) {
- spin_unlock_irqrestore(&fifo->tx_lock, flags);
- return NETDEV_TX_BUSY;
- }
+ if (vxge_netif_queue_stopped(fifo)) {
+ spin_unlock_irqrestore(&fifo->tx_lock, flags);
+ return NETDEV_TX_BUSY;
}
+
avail = vxge_hw_fifo_free_txdl_count_get(fifo_hw);
if (avail == 0) {
vxge_debug_tx(VXGE_ERR,
@@ -1478,7 +1445,7 @@ static int vxge_reset_vpath(struct vxgedev *vdev, int vp_id)
clear_bit(vp_id, &vdev->vp_reset);
/* Start the vpath queue */
- vxge_wake_tx_queue(&vdev->vpaths[vp_id].fifo, NULL);
+ vxge_wake_tx_queue(&vdev->vpaths[vp_id].fifo);
return ret;
}
@@ -1513,7 +1480,7 @@ static int do_vxge_reset(struct vxgedev *vdev, int event)
"%s: execution mode is debug, returning..",
vdev->ndev->name);
clear_bit(__VXGE_STATE_CARD_UP, &vdev->state);
- vxge_stop_all_tx_queue(vdev);
+ netif_tx_stop_all_queues(vdev->ndev);
return 0;
}
}
@@ -1523,7 +1490,7 @@ static int do_vxge_reset(struct vxgedev *vdev, int event)
switch (vdev->cric_err_event) {
case VXGE_HW_EVENT_UNKNOWN:
- vxge_stop_all_tx_queue(vdev);
+ netif_tx_stop_all_queues(vdev->ndev);
vxge_debug_init(VXGE_ERR,
"fatal: %s: Disabling device due to"
"unknown error",
@@ -1544,7 +1511,7 @@ static int do_vxge_reset(struct vxgedev *vdev, int event)
case VXGE_HW_EVENT_VPATH_ERR:
break;
case VXGE_HW_EVENT_CRITICAL_ERR:
- vxge_stop_all_tx_queue(vdev);
+ netif_tx_stop_all_queues(vdev->ndev);
vxge_debug_init(VXGE_ERR,
"fatal: %s: Disabling device due to"
"serious error",
@@ -1554,7 +1521,7 @@ static int do_vxge_reset(struct vxgedev *vdev, int event)
ret = -EPERM;
goto out;
case VXGE_HW_EVENT_SERR:
- vxge_stop_all_tx_queue(vdev);
+ netif_tx_stop_all_queues(vdev->ndev);
vxge_debug_init(VXGE_ERR,
"fatal: %s: Disabling device due to"
"serious error",
@@ -1566,7 +1533,7 @@ static int do_vxge_reset(struct vxgedev *vdev, int event)
ret = -EPERM;
goto out;
case VXGE_HW_EVENT_SLOT_FREEZE:
- vxge_stop_all_tx_queue(vdev);
+ netif_tx_stop_all_queues(vdev->ndev);
vxge_debug_init(VXGE_ERR,
"fatal: %s: Disabling device due to"
"slot freeze",
@@ -1580,7 +1547,7 @@ static int do_vxge_reset(struct vxgedev *vdev, int event)
}
if ((event == VXGE_LL_FULL_RESET) || (event == VXGE_LL_START_RESET))
- vxge_stop_all_tx_queue(vdev);
+ netif_tx_stop_all_queues(vdev->ndev);
if (event == VXGE_LL_FULL_RESET) {
status = vxge_reset_all_vpaths(vdev);
@@ -1640,7 +1607,7 @@ static int do_vxge_reset(struct vxgedev *vdev, int event)
vxge_hw_vpath_rx_doorbell_init(vdev->vpaths[i].handle);
}
- vxge_wake_all_tx_queue(vdev);
+ netif_tx_wake_all_queues(vdev->ndev);
}
out:
@@ -2779,7 +2746,7 @@ vxge_open(struct net_device *dev)
vxge_hw_vpath_rx_doorbell_init(vdev->vpaths[i].handle);
}
- vxge_start_all_tx_queue(vdev);
+ netif_tx_start_all_queues(vdev->ndev);
goto out0;
out2:
@@ -2902,7 +2869,7 @@ int do_vxge_close(struct net_device *dev, int do_io)
netif_carrier_off(vdev->ndev);
printk(KERN_NOTICE "%s: Link Down\n", vdev->ndev->name);
- vxge_stop_all_tx_queue(vdev);
+ netif_tx_stop_all_queues(vdev->ndev);
/* Note that at this point xmit() is stopped by upper layer */
if (do_io)
@@ -3215,7 +3182,7 @@ int __devinit vxge_device_register(struct __vxge_hw_device *hldev,
u64 stat;
*vdev_out = NULL;
- if (config->tx_steering_type == TX_MULTIQ_STEERING)
+ if (config->tx_steering_type)
no_of_queue = no_of_vpath;
ndev = alloc_etherdev_mq(sizeof(struct vxgedev),
@@ -3284,9 +3251,6 @@ int __devinit vxge_device_register(struct __vxge_hw_device *hldev,
if (vdev->config.gro_enable)
ndev->features |= NETIF_F_GRO;
- if (vdev->config.tx_steering_type == TX_MULTIQ_STEERING)
- ndev->real_num_tx_queues = no_of_vpath;
-
#ifdef NETIF_F_LLTX
ndev->features |= NETIF_F_LLTX;
#endif
diff --git a/drivers/net/vxge/vxge-main.h b/drivers/net/vxge/vxge-main.h
index 60276b2..a384582 100644
--- a/drivers/net/vxge/vxge-main.h
+++ b/drivers/net/vxge/vxge-main.h
@@ -228,10 +228,6 @@ struct vxge_fifo {
int tx_steering_type;
int indicate_max_pkts;
spinlock_t tx_lock;
- /* flag used to maintain queue state when MULTIQ is not enabled */
-#define VPATH_QUEUE_START 0
-#define VPATH_QUEUE_STOP 1
- int queue_state;
/* Tx stats */
struct vxge_fifo_stats stats;
@@ -447,13 +443,9 @@ int vxge_open_vpaths(struct vxgedev *vdev);
enum vxge_hw_status vxge_reset_all_vpaths(struct vxgedev *vdev);
-void vxge_stop_all_tx_queue(struct vxgedev *vdev);
-
void vxge_stop_tx_queue(struct vxge_fifo *fifo);
-void vxge_start_all_tx_queue(struct vxgedev *vdev);
-
-void vxge_wake_tx_queue(struct vxge_fifo *fifo, struct sk_buff *skb);
+void vxge_wake_tx_queue(struct vxge_fifo *fifo);
enum vxge_hw_status vxge_add_mac_addr(struct vxgedev *vdev,
struct macInfo *mac);
--
1.7.0.4
^ permalink raw reply related
* [PATCH 5/8] drivers: ixgbevf: fix unsigned underflow
From: Kulikov Vasiliy @ 2010-07-15 18:45 UTC (permalink / raw)
To: kernel-janitors
Cc: David S. Miller, Jeff Kirsher, Greg Rose, Eric Dumazet,
Joe Perches, netdev
'count' is unsigned. It is initialized to zero, then it can be increased
multiple times, and finally it is used in such a way:
>>>> count--;
|
| /* clear timestamp and dma mappings for remaining portion of packet */
| while (count >= 0) {
| count--;
| ...
^
If count is zero here (so, it was never increased), we would have a very
long loop :)
Signed-off-by: Kulikov Vasiliy <segooon@gmail.com>
---
drivers/net/ixgbevf/ixgbevf_main.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c
index 73f1e75..af49135 100644
--- a/drivers/net/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ixgbevf/ixgbevf_main.c
@@ -2935,7 +2935,8 @@ static int ixgbevf_tx_map(struct ixgbevf_adapter *adapter,
struct ixgbevf_tx_buffer *tx_buffer_info;
unsigned int len;
unsigned int total = skb->len;
- unsigned int offset = 0, size, count = 0;
+ unsigned int offset = 0, size;
+ int count = 0;
unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
unsigned int f;
int i;
--
1.7.0.4
^ permalink raw reply related
* [PATCH 4/8] drivers: irda: fix sign bug
From: Kulikov Vasiliy @ 2010-07-15 18:45 UTC (permalink / raw)
To: kernel-janitors
Cc: Samuel Ortiz, David S. Miller, Kuninori Morimoto, Tejun Heo,
netdev
platform_get_irq_byname() can return negative results, it is not seen to
unsigned irq. Make it signed.
Signed-off-by: Kulikov Vasiliy <segooon@gmail.com>
---
drivers/net/irda/sh_sir.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/irda/sh_sir.c b/drivers/net/irda/sh_sir.c
index 5c5f99d..00b38bc 100644
--- a/drivers/net/irda/sh_sir.c
+++ b/drivers/net/irda/sh_sir.c
@@ -709,7 +709,7 @@ static int __devinit sh_sir_probe(struct platform_device *pdev)
struct sh_sir_self *self;
struct resource *res;
char clk_name[8];
- unsigned int irq;
+ int irq;
int err = -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
--
1.7.0.4
^ permalink raw reply related
* [PATCH 08/25] atm: Convert pci_table entries to PCI_VDEVICE (if PCI_ANY_ID is used)
From: Peter Huewe @ 2010-07-15 18:45 UTC (permalink / raw)
To: Kernel Janitors
Cc: Chas Williams, David S. Miller, H Hartley Sweeten, Tejun Heo,
linux-atm-general, netdev, linux-kernel
From: Peter Huewe <peterhuewe@gmx.de>
This patch converts pci_table entries, where .subvendor=PCI_ANY_ID and
.subdevice=PCI_ANY_ID, .class=0 and .class_mask=0, to use the
PCI_VDEVICE macro, and thus improves readability.
Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
---
drivers/atm/idt77252.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c
index 558ad18..1679cbf 100644
--- a/drivers/atm/idt77252.c
+++ b/drivers/atm/idt77252.c
@@ -3779,8 +3779,7 @@ err_out_disable_pdev:
static struct pci_device_id idt77252_pci_tbl[] =
{
- { PCI_VENDOR_ID_IDT, PCI_DEVICE_ID_IDT_IDT77252,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+ { PCI_VDEVICE(IDT, PCI_DEVICE_ID_IDT_IDT77252), 0 },
{ 0, }
};
--
1.7.1
^ permalink raw reply related
* [PATCH 3/8] drivers: irda: fix sign bug
From: Kulikov Vasiliy @ 2010-07-15 18:44 UTC (permalink / raw)
To: kernel-janitors; +Cc: Samuel Ortiz, David S. Miller, Kuninori Morimoto, netdev
platform_get_irq_byname() can return negative results, it is not seen to
unsigned irq. Make it signed.
Signed-off-by: Kulikov Vasiliy <segooon@gmail.com>
---
drivers/net/irda/sh_irda.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/irda/sh_irda.c b/drivers/net/irda/sh_irda.c
index 9a828b0..edd5666 100644
--- a/drivers/net/irda/sh_irda.c
+++ b/drivers/net/irda/sh_irda.c
@@ -749,7 +749,7 @@ static int __devinit sh_irda_probe(struct platform_device *pdev)
struct sh_irda_self *self;
struct resource *res;
char clk_name[8];
- unsigned int irq;
+ int irq;
int err = -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
--
1.7.0.4
^ permalink raw reply related
* [PATCH 07/25] atm: Convert pci_table entries to PCI_VDEVICE (if PCI_ANY_ID is used)
From: Peter Huewe @ 2010-07-15 18:44 UTC (permalink / raw)
To: Kernel Janitors
Cc: Chas Williams, David S. Miller, Roel Kluin, Eric Dumazet,
Tejun Heo, linux-atm-general, netdev, linux-kernel
From: Peter Huewe <peterhuewe@gmx.de>
This patch converts pci_table entries, where .subvendor=PCI_ANY_ID and
.subdevice=PCI_ANY_ID, .class=0 and .class_mask=0, to use the
PCI_VDEVICE macro, and thus improves readability.
Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
---
drivers/atm/he.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/drivers/atm/he.c b/drivers/atm/he.c
index fa4d600..801e8b6 100644
--- a/drivers/atm/he.c
+++ b/drivers/atm/he.c
@@ -2870,8 +2870,7 @@ module_param(sdh, bool, 0);
MODULE_PARM_DESC(sdh, "use SDH framing (default 0)");
static struct pci_device_id he_pci_tbl[] = {
- { PCI_VENDOR_ID_FORE, PCI_DEVICE_ID_FORE_HE, PCI_ANY_ID, PCI_ANY_ID,
- 0, 0, 0 },
+ { PCI_VDEVICE(FORE, PCI_DEVICE_ID_FORE_HE), 0 },
{ 0, }
};
--
1.7.1
^ permalink raw reply related
* [PATCH 06/25] atm: Convert pci_table entries to PCI_VDEVICE (if PCI_ANY_ID is used)
From: Peter Huewe @ 2010-07-15 18:42 UTC (permalink / raw)
To: Kernel Janitors
Cc: Chas Williams, David S. Miller, Tejun Heo, linux-atm-general,
netdev, linux-kernel
From: Peter Huewe <peterhuewe@gmx.de>
This patch converts pci_table entries, where .subvendor=PCI_ANY_ID and
.subdevice=PCI_ANY_ID, .class=0 and .class_mask=0, to use the
PCI_VDEVICE macro, and thus improves readability.
Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
---
drivers/atm/firestream.c | 6 ++----
1 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c
index 6e600af..8717809 100644
--- a/drivers/atm/firestream.c
+++ b/drivers/atm/firestream.c
@@ -2027,10 +2027,8 @@ static void __devexit firestream_remove_one (struct pci_dev *pdev)
}
static struct pci_device_id firestream_pci_tbl[] = {
- { PCI_VENDOR_ID_FUJITSU_ME, PCI_DEVICE_ID_FUJITSU_FS50,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FS_IS50},
- { PCI_VENDOR_ID_FUJITSU_ME, PCI_DEVICE_ID_FUJITSU_FS155,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FS_IS155},
+ { PCI_VDEVICE(FUJITSU_ME, PCI_DEVICE_ID_FUJITSU_FS50), FS_IS50},
+ { PCI_VDEVICE(FUJITSU_ME, PCI_DEVICE_ID_FUJITSU_FS155), FS_IS155},
{ 0, }
};
--
1.7.1
^ permalink raw reply related
* [PATCH 05/25] atm: Convert pci_table entries to PCI_VDEVICE (if PCI_ANY_ID is used)
From: Peter Huewe @ 2010-07-15 18:41 UTC (permalink / raw)
To: Kernel Janitors
Cc: Chas Williams, David S. Miller, Eric Dumazet, Tejun Heo,
linux-atm-general, netdev, linux-kernel
From: Peter Huewe <peterhuewe@gmx.de>
This patch converts pci_table entries, where .subvendor=PCI_ANY_ID and
.subdevice=PCI_ANY_ID, .class=0 and .class_mask=0, to use the
PCI_VDEVICE macro, and thus improves readability.
Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
---
drivers/atm/eni.c | 6 ++----
1 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c
index 90a5a7c..80f9f36 100644
--- a/drivers/atm/eni.c
+++ b/drivers/atm/eni.c
@@ -2269,10 +2269,8 @@ out0:
static struct pci_device_id eni_pci_tbl[] = {
- { PCI_VENDOR_ID_EF, PCI_DEVICE_ID_EF_ATM_FPGA, PCI_ANY_ID, PCI_ANY_ID,
- 0, 0, 0 /* FPGA */ },
- { PCI_VENDOR_ID_EF, PCI_DEVICE_ID_EF_ATM_ASIC, PCI_ANY_ID, PCI_ANY_ID,
- 0, 0, 1 /* ASIC */ },
+ { PCI_VDEVICE(EF, PCI_DEVICE_ID_EF_ATM_FPGA), 0 /* FPGA */ },
+ { PCI_VDEVICE(EF, PCI_DEVICE_ID_EF_ATM_ASIC), 1 /* ASIC */ },
{ 0, }
};
MODULE_DEVICE_TABLE(pci,eni_pci_tbl);
--
1.7.1
^ permalink raw reply related
* Re: [PATCH] CAN: Add Flexcan CAN controller driver
From: Wolfgang Grandegger @ 2010-07-15 18:38 UTC (permalink / raw)
To: Marc Kleine-Budde
Cc: socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1279144811-12251-1-git-send-email-mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
Hi Marc,
On 07/15/2010 12:00 AM, Marc Kleine-Budde wrote:
> From: Sascha Hauer <s.hauer-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
>
> This core is found on some Freescale SoCs and also some Coldfire
> SoCs. Support for Coldfire is missing though at the moment as
> they have an older revision of the core which does not have RX FIFO
> support.
>
> Signed-off-by: Sascha Hauer <s.hauer-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
> Signed-off-by: Marc Kleine-Budde <mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
> ---
>
> Changes to prev version:
> * The is now GPLv2 (only) as no one complained.
>
> The patch applies to current net-next-2.6/master.
> If there aren't any objections please consider applying this patch.
> Wolfgang, can I an Acked-by?
I realized a few issues. You can add my "acked-by" when they are fixed.
>
> Cheers, Marc
>
> P.S.:
> This patch can be pulled, too:
>
> The following changes since commit fae88f7eedae42c955075aec7a0cd27545f81511:
>
> Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 (2010-07-13 14:25:13 -0700)
>
> are available in the git repository at:
>
> git://git.pengutronix.de/git/mkl/linux-2.6.git for-net-next-2.6
>
> Sascha Hauer (1):
> CAN: Add Flexcan CAN controller driver
>
> drivers/net/can/Kconfig | 6 +
> drivers/net/can/Makefile | 1 +
> drivers/net/can/flexcan.c | 1005 ++++++++++++++++++++++++++++++++++
> include/linux/can/platform/flexcan.h | 20 +
> 4 files changed, 1032 insertions(+), 0 deletions(-)
> create mode 100644 drivers/net/can/flexcan.c
> create mode 100644 include/linux/can/platform/flexcan.h
>
> diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
> index 2c5227c..3f13299 100644
> --- a/drivers/net/can/Kconfig
> +++ b/drivers/net/can/Kconfig
> @@ -73,6 +73,12 @@ config CAN_JANZ_ICAN3
> This driver can also be built as a module. If so, the module will be
> called janz-ican3.ko.
>
> +config CAN_FLEXCAN
> + tristate "Support for Freescale FLEXCAN based chips"
> + depends on CAN_DEV
Some more arch specific dependencies would be nice.
> + ---help---
> + Say Y here if you want to support for Freescale FlexCAN.
> +
> source "drivers/net/can/mscan/Kconfig"
>
> source "drivers/net/can/sja1000/Kconfig"
> diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
> index 9047cd0..0057537 100644
> --- a/drivers/net/can/Makefile
> +++ b/drivers/net/can/Makefile
> @@ -16,5 +16,6 @@ obj-$(CONFIG_CAN_TI_HECC) += ti_hecc.o
> obj-$(CONFIG_CAN_MCP251X) += mcp251x.o
> obj-$(CONFIG_CAN_BFIN) += bfin_can.o
> obj-$(CONFIG_CAN_JANZ_ICAN3) += janz-ican3.o
> +obj-$(CONFIG_CAN_FLEXCAN) += flexcan.o
>
> ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
> diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
> new file mode 100644
> index 0000000..a3180ba
> --- /dev/null
> +++ b/drivers/net/can/flexcan.c
> @@ -0,0 +1,1005 @@
> +/*
> + * flexcan.c - FLEXCAN CAN controller driver
> + *
> + * Copyright (c) 2005-2006 Varma Electronics Oy
> + * Copyright (c) 2009 Sascha Hauer, Pengutronix
> + * Copyright (c) 2010 Marc Kleine-Budde, Pengutronix
> + *
> + * Based on code originally by Andrey Volkov <avolkov-ppI4tVfbJvJWk0Htik3J/w@public.gmane.org>
> + *
> + * LICENCE:
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation version 2.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + */
> +
> +#include <linux/netdevice.h>
> +#include <linux/can.h>
> +#include <linux/can/dev.h>
> +#include <linux/can/error.h>
> +#include <linux/can/platform/flexcan.h>
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/if_arp.h>
> +#include <linux/if_ether.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/list.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +
> +
> +#include <mach/clock.h>
> +
> +#define DRV_NAME "flexcan"
> +#define FLEXCAN_NAPI_WEIGHT 8
> +
> +
> +/* FLEXCAN module configuration register (CANMCR) bits */
> +#define FLEXCAN_MCR_MDIS BIT(31)
> +#define FLEXCAN_MCR_FRZ BIT(30)
> +#define FLEXCAN_MCR_FEN BIT(29)
> +#define FLEXCAN_MCR_HALT BIT(28)
> +#define FLEXCAN_MCR_NOT_RDY BIT(27)
> +#define FLEXCAN_MCR_WAK_MSK BIT(26)
> +#define FLEXCAN_MCR_SOFTRST BIT(25)
> +#define FLEXCAN_MCR_FRZ_ACK BIT(24)
> +#define FLEXCAN_MCR_SUPV BIT(23)
> +#define FLEXCAN_MCR_SLF_WAK BIT(22)
> +#define FLEXCAN_MCR_WRN_EN BIT(21)
> +#define FLEXCAN_MCR_LPM_ACK BIT(20)
> +#define FLEXCAN_MCR_WAK_SRC BIT(19)
> +#define FLEXCAN_MCR_DOZE BIT(18)
> +#define FLEXCAN_MCR_SRX_DIS BIT(17)
> +#define FLEXCAN_MCR_BCC BIT(16)
> +#define FLEXCAN_MCR_LPRIO_EN BIT(13)
> +#define FLEXCAN_MCR_AEN BIT(12)
> +#define FLEXCAN_MCR_MAXMB(x) ((x) & 0xf)
> +#define FLEXCAN_MCR_IDAM_A (0 << 8)
> +#define FLEXCAN_MCR_IDAM_B (1 << 8)
> +#define FLEXCAN_MCR_IDAM_C (2 << 8)
> +#define FLEXCAN_MCR_IDAM_D (3 << 8)
> +
> +/* FLEXCAN control register (CANCTRL) bits */
> +#define FLEXCAN_CTRL_PRESDIV(x) (((x) & 0xff) << 24)
> +#define FLEXCAN_CTRL_RJW(x) (((x) & 0x03) << 22)
> +#define FLEXCAN_CTRL_PSEG1(x) (((x) & 0x07) << 19)
> +#define FLEXCAN_CTRL_PSEG2(x) (((x) & 0x07) << 16)
> +#define FLEXCAN_CTRL_BOFF_MSK BIT(15)
> +#define FLEXCAN_CTRL_ERR_MSK BIT(14)
> +#define FLEXCAN_CTRL_CLK_SRC BIT(13)
> +#define FLEXCAN_CTRL_LPB BIT(12)
> +#define FLEXCAN_CTRL_TWRN_MSK BIT(11)
> +#define FLEXCAN_CTRL_RWRN_MSK BIT(10)
> +#define FLEXCAN_CTRL_SMP BIT(7)
> +#define FLEXCAN_CTRL_BOFF_REC BIT(6)
> +#define FLEXCAN_CTRL_TSYNC BIT(5)
> +#define FLEXCAN_CTRL_LBUF BIT(4)
> +#define FLEXCAN_CTRL_LOM BIT(3)
> +#define FLEXCAN_CTRL_PROPSEG(x) ((x) & 0x07)
> +
> +/* FLEXCAN error and status register (ESR) bits */
> +#define FLEXCAN_ESR_TWRN_INT BIT(17)
> +#define FLEXCAN_ESR_RWRN_INT BIT(16)
> +#define FLEXCAN_ESR_BIT1_ERR BIT(15)
> +#define FLEXCAN_ESR_BIT0_ERR BIT(14)
> +#define FLEXCAN_ESR_ACK_ERR BIT(13)
> +#define FLEXCAN_ESR_CRC_ERR BIT(12)
> +#define FLEXCAN_ESR_FRM_ERR BIT(11)
> +#define FLEXCAN_ESR_STF_ERR BIT(10)
> +#define FLEXCAN_ESR_TX_WRN BIT(9)
> +#define FLEXCAN_ESR_RX_WRN BIT(8)
> +#define FLEXCAN_ESR_IDLE BIT(7)
> +#define FLEXCAN_ESR_TXRX BIT(6)
> +#define FLEXCAN_EST_FLT_CONF_SHIFT (4)
> +#define FLEXCAN_ESR_FLT_CONF_MASK (0x2 << FLEXCAN_EST_FLT_CONF_SHIFT)
> +#define FLEXCAN_ESR_FLT_CONF_ACTIVE (0x0 << FLEXCAN_EST_FLT_CONF_SHIFT)
> +#define FLEXCAN_ESR_FLT_CONF_PASSIVE (0x1 << FLEXCAN_EST_FLT_CONF_SHIFT)
> +#define FLEXCAN_ESR_BOFF_INT BIT(2)
> +#define FLEXCAN_ESR_ERR_INT BIT(1)
> +#define FLEXCAN_ESR_WAK_INT BIT(0)
> +#define FLEXCAN_ESR_ERR_FRAME \
> + (FLEXCAN_ESR_BIT1_ERR | FLEXCAN_ESR_BIT0_ERR | \
> + FLEXCAN_ESR_ACK_ERR | FLEXCAN_ESR_CRC_ERR | \
> + FLEXCAN_ESR_FRM_ERR | FLEXCAN_ESR_STF_ERR)
> +#define FLEXCAN_ESR_ERR_LINE \
> + (FLEXCAN_ESR_TWRN_INT | FLEXCAN_ESR_RWRN_INT | FLEXCAN_ESR_BOFF_INT)
> +
> +/* FLEXCAN interrupt flag register (IFLAG) bits */
> +#define FLEXCAN_TX_BUF_ID 8
> +#define FLEXCAN_IFLAG_BUF(x) BIT(x)
> +#define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7)
> +#define FLEXCAN_IFLAG_RX_FIFO_WARN BIT(6)
> +#define FLEXCAN_IFLAG_RX_FIFO_AVAILABLE BIT(5)
> +#define FLEXCAN_IFLAG_DEFAULT \
> + (FLEXCAN_IFLAG_RX_FIFO_OVERFLOW | FLEXCAN_IFLAG_RX_FIFO_AVAILABLE | \
> + FLEXCAN_IFLAG_BUF(FLEXCAN_TX_BUF_ID))
> +
> +/* FLEXCAN message buffers */
> +#define FLEXCAN_MB_CNT_CODE(x) (((x) & 0xf) << 24)
> +#define FLEXCAN_MB_CNT_SRR BIT(22)
> +#define FLEXCAN_MB_CNT_IDE BIT(21)
> +#define FLEXCAN_MB_CNT_RTR BIT(20)
> +#define FLEXCAN_MB_CNT_LENGTH(x) (((x) & 0xf) << 16)
> +#define FLEXCAN_MB_CNT_TIMESTAMP(x) ((x) & 0xffff)
> +
> +#define FLEXCAN_MB_CODE_MASK (0xf0ffffff)
> +
> +/* Structure of the message buffer */
> +struct flexcan_mb {
> + u32 can_ctrl;
> + u32 can_id;
> + u32 data[2];
> +};
> +
> +/* Structure of the hardware registers */
> +struct flexcan_regs {
> + u32 mcr; /* 0x00 */
> + u32 ctrl; /* 0x04 */
> + u32 timer; /* 0x08 */
> + u32 _reserved1; /* 0x0c */
> + u32 rxgmask; /* 0x10 */
> + u32 rx14mask; /* 0x14 */
> + u32 rx15mask; /* 0x18 */
> + u32 ecr; /* 0x1c */
> + u32 esr; /* 0x20 */
> + u32 imask2; /* 0x24 */
> + u32 imask1; /* 0x28 */
> + u32 iflag2; /* 0x2c */
> + u32 iflag1; /* 0x30 */
> + u32 _reserved2[19];
> + struct flexcan_mb cantxfg[64];
> +};
> +
> +struct flexcan_priv {
> + struct can_priv can;
> + struct net_device *dev;
> + struct napi_struct napi;
> +
> + void __iomem *base;
> + u32 reg_esr;
> + u32 reg_ctrl_default;
> +
> + struct clk *clk;
> + struct flexcan_platform_data *pdata;
> +};
> +
> +static struct can_bittiming_const flexcan_bittiming_const = {
> + .name = DRV_NAME,
> + .tseg1_min = 4,
> + .tseg1_max = 16,
> + .tseg2_min = 2,
> + .tseg2_max = 8,
> + .sjw_max = 4,
> + .brp_min = 1,
> + .brp_max = 256,
> + .brp_inc = 1,
> +};
> +
> +/*
> + * Swtich transceiver on or off
> + */
> +static void flexcan_transceiver_switch(const struct flexcan_priv *priv, int on)
> +{
> + if (priv->pdata && priv->pdata->transceiver_switch)
> + priv->pdata->transceiver_switch(on);
> +}
> +
> +static inline void flexcan_chip_enable(struct flexcan_priv *priv)
> +{
> + struct flexcan_regs __iomem *regs = priv->base;
> + u32 reg;
> +
> + reg = readl(®s->mcr);
> + reg &= ~FLEXCAN_MCR_MDIS;
> + writel(reg, ®s->mcr);
> +
> + udelay(10);
> +}
> +
> +static inline void flexcan_chip_disable(struct flexcan_priv *priv)
> +{
> + struct flexcan_regs __iomem *regs = priv->base;
> + u32 reg;
> +
> + reg = readl(®s->mcr);
> + reg |= FLEXCAN_MCR_MDIS;
> + writel(reg, ®s->mcr);
> +}
> +
> +static int flexcan_get_berr_counter(const struct net_device *dev,
> + struct can_berr_counter *bec)
> +{
> + const struct flexcan_priv *priv = netdev_priv(dev);
> + struct flexcan_regs __iomem *regs = priv->base;
> + u32 reg = readl(®s->ecr);
> +
> + bec->txerr = (reg >> 0) & 0xff;
> + bec->rxerr = (reg >> 8) & 0xff;
> +
> + return 0;
> +}
> +
> +
> +static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)
> +{
> + const struct flexcan_priv *priv = netdev_priv(dev);
> + struct net_device_stats *stats = &dev->stats;
> + struct flexcan_regs __iomem *regs = priv->base;
> + struct can_frame *frame = (struct can_frame *)skb->data;
> + u32 can_id;
> + u32 ctrl = FLEXCAN_MB_CNT_CODE(0xc) | (frame->can_dlc << 16);
> +
> + if (can_dropped_invalid_skb(dev, skb))
> + return NETDEV_TX_OK;
> +
> + netif_stop_queue(dev);
> +
> + if (frame->can_id & CAN_EFF_FLAG) {
> + can_id = frame->can_id & CAN_EFF_MASK;
> + ctrl |= FLEXCAN_MB_CNT_IDE | FLEXCAN_MB_CNT_SRR;
> + } else {
> + can_id = (frame->can_id & CAN_SFF_MASK) << 18;
> + }
> +
> + if (frame->can_id & CAN_RTR_FLAG)
> + ctrl |= FLEXCAN_MB_CNT_RTR;
> +
> + if (frame->can_dlc > 0) {
> + u32 data;
> + data = frame->data[0] << 24;
> + data |= frame->data[1] << 16;
> + data |= frame->data[2] << 8;
> + data |= frame->data[3];
> + writel(data, ®s->cantxfg[FLEXCAN_TX_BUF_ID].data[0]);
> + }
IIRC, in your review of Jürgens patch you suggested to use be32_to_cpu here.
> + if (frame->can_dlc > 3) {
> + u32 data;
> + data = frame->data[4] << 24;
> + data |= frame->data[5] << 16;
> + data |= frame->data[6] << 8;
> + data |= frame->data[7];
> + writel(data, ®s->cantxfg[FLEXCAN_TX_BUF_ID].data[1]);
> + }
Ditto.
> + writel(can_id, ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_id);
> + writel(ctrl, ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl);
> +
> + kfree_skb(skb);
> +
> + stats->tx_bytes += frame->can_dlc;
> +
> + return NETDEV_TX_OK;
> +}
> +
> +
> +static void flexcan_poll_err_frame(struct net_device *dev,
> + struct can_frame *cf, u32 reg_esr)
> +{
> + struct flexcan_priv *priv = netdev_priv(dev);
> + int error_warning = 0, rx_errors = 0, tx_errors = 0;
> +
> + if (reg_esr & FLEXCAN_ESR_BIT1_ERR) {
> + rx_errors = 1;
> + cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
> + cf->data[2] |= CAN_ERR_PROT_BIT1;
> + }
> +
> + if (reg_esr & FLEXCAN_ESR_BIT0_ERR) {
> + rx_errors = 1;
> + cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
> + cf->data[2] |= CAN_ERR_PROT_BIT0;
> + }
> +
> + if (reg_esr & FLEXCAN_ESR_FRM_ERR) {
> + rx_errors = 1;
> + cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
> + cf->data[2] |= CAN_ERR_PROT_FORM;
> + }
> +
> + if (reg_esr & FLEXCAN_ESR_STF_ERR) {
> + rx_errors = 1;
> + cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
> + cf->data[2] |= CAN_ERR_PROT_STUFF;
> + }
> +
> +
> + if (reg_esr & FLEXCAN_ESR_ACK_ERR) {
> + tx_errors = 1;
> + cf->can_id |= CAN_ERR_ACK;
This is a bus-error as well. Therefore I think it should be:
if (reg_esr & FLEXCAN_ESR_ACK_ERR) {
tx_errors = 1;
cf->can_id |= CAN_ERR_ACK;
cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
cf->data[3] |= CAN_ERR_PROT_LOC_ACK; /* ACK slot */
}
I need to check what CAN_ERR_ACK is intended for. Then, cf->can_id could
be preset with "CAN_ERR_PROT | CAN_ERR_BUSERROR" at the beginning.
> + }
> +
> + if (error_warning)
> + priv->can.can_stats.error_warning++;
Hm, error_warning is always 0 !?
> + if (rx_errors)
> + dev->stats.rx_errors++;
> + if (tx_errors)
> + dev->stats.tx_errors++;
> +
> +}
> +
> +static void flexcan_poll_err(struct net_device *dev, u32 reg_esr)
> +{
> + struct sk_buff *skb;
> + struct can_frame *cf;
> +
> + skb = alloc_can_err_skb(dev, &cf);
> + if (unlikely(!skb))
> + return;
> +
> + flexcan_poll_err_frame(dev, cf, reg_esr);
> + netif_receive_skb(skb);
> +
> + dev->stats.rx_packets++;
> + dev->stats.rx_bytes += cf->can_dlc;
> +}
> +
> +static void flexcan_read_fifo(const struct net_device *dev, struct can_frame *cf)
> +{
> + const struct flexcan_priv *priv = netdev_priv(dev);
> + struct flexcan_regs __iomem *regs = priv->base;
> + struct flexcan_mb __iomem *mb = ®s->cantxfg[0];
> + u32 reg_ctrl, reg_id;
> +
> + reg_ctrl = readl(&mb->can_ctrl);
> + reg_id = readl(&mb->can_id);
> + if (reg_ctrl & FLEXCAN_MB_CNT_IDE)
> + cf->can_id = ((reg_id >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG;
> + else
> + cf->can_id = (reg_id >> 18) & CAN_SFF_MASK;
> +
> + if (reg_ctrl & FLEXCAN_MB_CNT_RTR)
> + cf->can_id |= CAN_RTR_FLAG;
> + cf->can_dlc = get_can_dlc((reg_ctrl >> 16) & 0xf);
> +
> + *(__be32 *)(cf->data + 0) = cpu_to_be32(readl(&mb->data[0]));
> + *(__be32 *)(cf->data + 4) = cpu_to_be32(readl(&mb->data[1]));
> +
> + /* mark as read */
> + writel(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1);
> + readl(®s->timer);
> +}
> +
> +static void flexcan_read_frame(struct net_device *dev)
> +{
> + struct net_device_stats *stats = &dev->stats;
> + struct can_frame *cf;
> + struct sk_buff *skb;
> +
> + skb = alloc_can_skb(dev, &cf);
> + if (unlikely(!skb)) {
> + stats->rx_dropped++;
> + return;
> + }
> +
> + flexcan_read_fifo(dev, cf);
> + netif_receive_skb(skb);
> +
> + stats->rx_packets++;
> + stats->rx_bytes += cf->can_dlc;
> +}
> +
> +static int flexcan_poll(struct napi_struct *napi, int quota)
> +{
> + struct net_device *dev = napi->dev;
> + const struct flexcan_priv *priv = netdev_priv(dev);
> + struct flexcan_regs __iomem *regs = priv->base;
> + u32 reg_iflag1, reg_esr;
> + int work_done = 0;
> +
> + reg_iflag1 = readl(®s->iflag1);
> +
> + /* first handle RX-FIFO */
> + while (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE &&
> + work_done < quota) {
> + flexcan_read_frame(dev);
> +
> + work_done++;
> + reg_iflag1 = readl(®s->iflag1);
> + }
> +
> + /*
> + * The error bits are clear on read,
> + * so use saved value from irq handler.
> + */
> + reg_esr = readl(®s->esr) | priv->reg_esr;
Re-reading reg_esr may cause lost of state changes.
> + if (work_done < quota) {
> + flexcan_poll_err(dev, reg_esr);
An error frame is created here for each call of flexcan_poll(), not only
in case of errors.
> + work_done++;
> + }
> +
> + if (work_done < quota) {
> + napi_complete(napi);
> + /* enable IRQs */
> + writel(FLEXCAN_IFLAG_DEFAULT, ®s->imask1);
> + writel(priv->reg_ctrl_default, ®s->ctrl);
> + }
> +
> + return work_done;
> +}
> +
> +static void flexcan_irq_err_state(struct net_device *dev,
> + struct can_frame *cf, enum can_state new_state)
> +{
> + struct flexcan_priv *priv = netdev_priv(dev);
> + struct can_berr_counter bec;
> +
> + flexcan_get_berr_counter(dev, &bec);
> +
> + switch (priv->can.state) {
> + case CAN_STATE_ERROR_ACTIVE:
> + /*
> + * from: ERROR_ACTIVE
> + * to : ERROR_WARNING, ERROR_PASSIVE, BUS_OFF
> + * => : there was a warning int
> + */
> + if (new_state >= CAN_STATE_ERROR_WARNING &&
> + new_state <= CAN_STATE_BUS_OFF) {
> + dev_dbg(dev->dev.parent, "Error Warning IRQ\n");
> + priv->can.can_stats.error_warning++;
> +
> + cf->can_id |= CAN_ERR_CRTL;
> + cf->data[1] = (bec.txerr > bec.rxerr) ?
> + CAN_ERR_CRTL_TX_WARNING :
> + CAN_ERR_CRTL_RX_WARNING;
> + }
> + case CAN_STATE_ERROR_WARNING: /* fallthrough */
> + /*
> + * from: ERROR_ACTIVE, ERROR_WARNING
> + * to : ERROR_PASSIVE, BUS_OFF
> + * => : error passive int
> + */
> + if (new_state >= CAN_STATE_ERROR_PASSIVE &&
> + new_state <= CAN_STATE_BUS_OFF) {
> + dev_dbg(dev->dev.parent, "Error Passive IRQ\n");
> + priv->can.can_stats.error_passive++;
> +
> + cf->can_id |= CAN_ERR_CRTL;
> + cf->data[1] = (bec.txerr > bec.rxerr) ?
> + CAN_ERR_CRTL_TX_PASSIVE :
> + CAN_ERR_CRTL_RX_PASSIVE;
> + }
> + break;
> + case CAN_STATE_BUS_OFF:
> + dev_err(dev->dev.parent,
> + "BUG! hardware recovered automatically from BUS_OFF\n");
> + break;
> + default:
> + break;
> + }
> +
> + /* process state changes depending on the new state */
> + switch (new_state) {
> + case CAN_STATE_BUS_OFF:
> + cf->can_id |= CAN_ERR_BUSOFF;
> + can_bus_off(dev);
> + break;
> + default:
> + break;
> + }
> +}
> +
> +static void flexcan_irq_err(struct net_device *dev)
> +{
> + struct flexcan_priv *priv = netdev_priv(dev);
> + struct flexcan_regs __iomem *regs = priv->base;
> + struct sk_buff *skb;
> + struct can_frame *cf;
> + enum can_state new_state;
> + u32 reg_esr;
> + int flt;
> +
> + reg_esr = readl(®s->esr);
As discussed, reg_esr is re-read here. Should probably be passed via
function argument.
> + writel(reg_esr, ®s->esr);
> +
> + flt = reg_esr & FLEXCAN_ESR_FLT_CONF_MASK;
> + if (likely(flt == FLEXCAN_ESR_FLT_CONF_ACTIVE)) {
> + if (likely(!(reg_esr & (FLEXCAN_ESR_TX_WRN |
> + FLEXCAN_ESR_RX_WRN))))
> + new_state = CAN_STATE_ERROR_ACTIVE;
> + else
> + new_state = CAN_STATE_ERROR_WARNING;
> + } else if (unlikely(flt == FLEXCAN_ESR_FLT_CONF_PASSIVE))
> + new_state = CAN_STATE_ERROR_PASSIVE;
> + else
> + new_state = CAN_STATE_BUS_OFF;
> +
> + /* state hasn't changed */
> + if (likely(new_state == priv->can.state))
> + return;
> +
> + skb = alloc_can_err_skb(dev, &cf);
> + if (unlikely(!skb))
> + return;
> +
> + flexcan_irq_err_state(dev, cf, new_state);
> + netif_rx(skb);
> +
> + dev->stats.rx_packets++;
> + dev->stats.rx_bytes += cf->can_dlc;
> +
> + priv->can.state = new_state;
> +}
> +
> +static irqreturn_t flexcan_irq(int irq, void *dev_id)
> +{
> + struct net_device *dev = dev_id;
> + struct net_device_stats *stats = &dev->stats;
> + struct flexcan_priv *priv = netdev_priv(dev);
> + struct flexcan_regs __iomem *regs = priv->base;
> + u32 reg_iflag1, reg_esr;
> +
> + reg_iflag1 = readl(®s->iflag1);
> + reg_esr = readl(®s->esr);
> +
> + /* receive or error interrupt -> napi */
> + if ((reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE) ||
> + (reg_esr & FLEXCAN_ESR_ERR_FRAME)) {
> + /*
> + * The error bits are cleared on read,
> + * save for later use.
> + */
> + priv->reg_esr = reg_esr;
> + writel(FLEXCAN_IFLAG_DEFAULT & ~FLEXCAN_IFLAG_RX_FIFO_AVAILABLE,
> + ®s->imask1);
> + writel(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_MSK,
> + ®s->ctrl);
> + napi_schedule(&priv->napi);
> + }
> +
> + /* FIFO overflow */
> + if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_OVERFLOW) {
> + writel(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW, ®s->iflag1);
> + dev->stats.rx_over_errors++;
> + dev->stats.rx_errors++;
> + }
> +
> + /* transmission complete interrupt */
> + if (reg_iflag1 & (1 << FLEXCAN_TX_BUF_ID)) {
> + stats->tx_packets++;
Where is stats->tx_bytes incremented?
> + writel((1 << FLEXCAN_TX_BUF_ID), ®s->iflag1);
> + netif_wake_queue(dev);
> + }
> +
> + /* handle state changes */
> + flexcan_irq_err(dev);
This does create and send an error message for *each* interrupt, even
for non-error interrupts (RX and TX).
Also, state changes are handled in the hard-irq context, while the
errors are handle in the soft-irq context. This looks tricky and error
prune to me as both are derived from the esr register. State changes and
errors might not be realized in the correct order, etc. It might be
saver to handle both in the poll routine by a common function.
> +
> + return IRQ_HANDLED;
> +}
> +
> +static void flexcan_set_bittiming(struct net_device *dev)
> +{
> + const struct flexcan_priv *priv = netdev_priv(dev);
> + const struct can_bittiming *bt = &priv->can.bittiming;
> + struct flexcan_regs __iomem *regs = priv->base;
> + u32 reg;
> +
> + reg = readl(®s->ctrl);
> + reg &= ~(FLEXCAN_CTRL_PRESDIV(0xff) |
> + FLEXCAN_CTRL_RJW(0x3) |
> + FLEXCAN_CTRL_PSEG1(0x7) |
> + FLEXCAN_CTRL_PSEG2(0x7) |
> + FLEXCAN_CTRL_PROPSEG(0x7) |
> + FLEXCAN_CTRL_LPB |
> + FLEXCAN_CTRL_SMP |
> + FLEXCAN_CTRL_LOM);
> +
> + reg |= FLEXCAN_CTRL_PRESDIV(bt->brp - 1) |
> + FLEXCAN_CTRL_PSEG1(bt->phase_seg1 - 1) |
> + FLEXCAN_CTRL_PSEG2(bt->phase_seg2 - 1) |
> + FLEXCAN_CTRL_RJW(bt->sjw - 1) |
> + FLEXCAN_CTRL_PROPSEG(bt->prop_seg - 1);
> +
> + if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)
> + reg |= FLEXCAN_CTRL_LPB;
> + if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
> + reg |= FLEXCAN_CTRL_LOM;
> + if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
> + reg |= FLEXCAN_CTRL_SMP;
> +
> + dev_info(dev->dev.parent, "writing ctrl=0x%08x\n", reg);
> + writel(reg, ®s->ctrl);
> +
> + /* print chip status */
> + dev_dbg(dev->dev.parent, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__,
> + readl(®s->mcr), readl(®s->ctrl));
This seems especially useful for development. Please check the other
dev_dbg's as well.
> +}
> +
> +/*
> + * flexcan_chip_start
> + *
> + * this functions is entered with clocks enabled
> + *
> + */
> +static int flexcan_chip_start(struct net_device *dev)
> +{
> + struct flexcan_priv *priv = netdev_priv(dev);
> + struct flexcan_regs __iomem *regs = priv->base;
> + unsigned int i;
> + int err;
> + u32 reg_mcr, reg_ctrl;
> +
> + /* enable module */
> + flexcan_chip_enable(priv);
> +
> + /* soft reset */
> + writel(FLEXCAN_MCR_SOFTRST, ®s->mcr);
> + udelay(10);
> +
> + reg_mcr = readl(®s->mcr);
> + if (reg_mcr & FLEXCAN_MCR_SOFTRST) {
> + dev_err(dev->dev.parent,
> + "Failed to softreset can module (mcr=0x%08x)\n", reg_mcr);
> + err = -ENODEV;
> + goto out;
> + }
> +
> + flexcan_set_bittiming(dev);
> +
> + /*
> + * MCR
> + *
> + * enable freeze
> + * enable fifo
> + * halt now
> + * only supervisor access
> + * enable warning int
> + * choose format C
> + *
> + */
> + reg_mcr = readl(®s->mcr);
> + reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_FEN | FLEXCAN_MCR_HALT |
> + FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN |
> + FLEXCAN_MCR_IDAM_C;
> + dev_dbg(dev->dev.parent, "%s: writing mcr=0x%08x", __func__, reg_mcr);
> + writel(reg_mcr, ®s->mcr);
> +
> + /*
> + * CTRL
> + *
> + * enable bus off interrupt
> + * disable auto busoff recovery
> + * enable tx and rx warning interrupt
> + * transmit lowest buffer first
> + */
> + reg_ctrl = readl(®s->ctrl);
> + reg_ctrl |= FLEXCAN_CTRL_BOFF_MSK |FLEXCAN_CTRL_BOFF_REC |
> + FLEXCAN_CTRL_TWRN_MSK | FLEXCAN_CTRL_RWRN_MSK |
> + FLEXCAN_CTRL_LBUF;
> + /*
> + * TODO: for now turn on the error interrupt, otherwise we
> + * don't get any warning or bus passive interrupts.
> + */
> + reg_ctrl |= FLEXCAN_CTRL_ERR_MSK;
> +
> + /* save for later use */
> + priv->reg_ctrl_default = reg_ctrl;
> + dev_dbg(dev->dev.parent, "%s: writing ctrl=0x%08x", __func__, reg_ctrl);
> + writel(reg_ctrl, ®s->ctrl);
> +
> + for (i = 0; i < ARRAY_SIZE(regs->cantxfg); i++) {
> + writel(0, ®s->cantxfg[i].can_ctrl);
> + writel(0, ®s->cantxfg[i].can_id);
> + writel(0, ®s->cantxfg[i].data[0]);
> + writel(0, ®s->cantxfg[i].data[1]);
> +
> + /* put MB into rx queue */
> + writel(FLEXCAN_MB_CNT_CODE(0x4), ®s->cantxfg[i].can_ctrl);
> + }
> +
> + /* acceptance mask/acceptance code (accept everything) */
> + writel(0x0, ®s->rxgmask);
> + writel(0x0, ®s->rx14mask);
> + writel(0x0, ®s->rx15mask);
> +
> + flexcan_transceiver_switch(priv, 1);
> +
> + /* synchronize with the can bus */
> + reg_mcr = readl(®s->mcr);
> + reg_mcr &= ~FLEXCAN_MCR_HALT;
> + writel(reg_mcr, ®s->mcr);
> +
> + priv->can.state = CAN_STATE_ERROR_ACTIVE;
> +
> + /* enable FIFO interrupts */
> + writel(FLEXCAN_IFLAG_DEFAULT, ®s->imask1);
> +
> + /* print chip status */
> + dev_dbg(dev->dev.parent, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__,
> + readl(®s->mcr), readl(®s->ctrl));
> +
> + return 0;
> +
> + out:
> + flexcan_chip_disable(priv);
> + return err;
> +}
> +
> +/*
> + * flexcan_chip_stop
> + *
> + * this functions is entered with clocks enabled
> + *
> + */
> +static void flexcan_chip_stop(struct net_device *dev)
> +{
> + struct flexcan_priv *priv = netdev_priv(dev);
> + struct flexcan_regs __iomem *regs = priv->base;
> + u32 reg;
> +
> + /* Disable all interrupts */
> + writel(0, ®s->imask1);
> +
> + /* Disable + halt module */
> + reg = readl(®s->mcr);
> + reg |= FLEXCAN_MCR_MDIS | FLEXCAN_MCR_HALT;
> + writel(reg, ®s->mcr);
> +
> + flexcan_transceiver_switch(priv, 0);
> + priv->can.state = CAN_STATE_STOPPED;
> +
> + return;
> +}
> +
> +static int flexcan_open(struct net_device *dev)
> +{
> + struct flexcan_priv *priv = netdev_priv(dev);
> + int err;
> +
> + clk_enable(priv->clk);
> +
> + err = open_candev(dev);
> + if (err)
> + goto out;
> +
> + err = request_irq(dev->irq, flexcan_irq, IRQF_SHARED, dev->name, dev);
> + if (err)
> + goto out_close;
> +
> + /* start chip and queuing */
> + err = flexcan_chip_start(dev);
> + if (err)
> + goto out_close;
> + napi_enable(&priv->napi);
> + netif_start_queue(dev);
> +
> + return 0;
> +
> + out_close:
> + close_candev(dev);
> + out:
> + clk_disable(priv->clk);
> +
> + return err;
> +}
> +
> +static int flexcan_close(struct net_device *dev)
> +{
> + struct flexcan_priv *priv = netdev_priv(dev);
> +
> + netif_stop_queue(dev);
> + napi_disable(&priv->napi);
> + flexcan_chip_stop(dev);
> +
> + free_irq(dev->irq, dev);
> + clk_disable(priv->clk);
> +
> + close_candev(dev);
> +
> + return 0;
> +}
> +
> +static int flexcan_set_mode(struct net_device *dev, enum can_mode mode)
> +{
> + int err;
> +
> + switch (mode) {
> + case CAN_MODE_START:
> + err = flexcan_chip_start(dev);
> + if (err)
> + return err;
> +
> + netif_wake_queue(dev);
> + break;
> +
> + default:
> + return -EOPNOTSUPP;
> + }
> +
> + return 0;
> +}
> +
> +static const struct net_device_ops flexcan_netdev_ops = {
> + .ndo_open = flexcan_open,
> + .ndo_stop = flexcan_close,
> + .ndo_start_xmit = flexcan_start_xmit,
> +};
> +
> +static int __devinit register_flexcandev(struct net_device *dev)
> +{
> + struct flexcan_priv *priv = netdev_priv(dev);
> + struct flexcan_regs __iomem *regs = priv->base;
> + u32 reg, err;
> +
> + clk_enable(priv->clk);
> +
> + /* select "bus clock", chip must be disabled */
> + flexcan_chip_disable(priv);
> + reg = readl(®s->ctrl);
> + reg |= FLEXCAN_CTRL_CLK_SRC;
> + writel(reg, ®s->ctrl);
> +
> + flexcan_chip_enable(priv);
> +
> + /* set freeze, halt and activate FIFO, restrict register access */
> + reg = readl(®s->mcr);
> + reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT |
> + FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV;
> + writel(reg, ®s->mcr);
> +
> + /*
> + * Currently we only support newer versions of this core
> + * featuring a RX FIFO. Older cores found on some Coldfire
> + * derivates are not yet supported.
> + */
> + reg = readl(®s->mcr);
> + if (!(reg & FLEXCAN_MCR_FEN)) {
> + dev_err(dev->dev.parent,
> + "Could not enable RX FIFO, unsupported core\n");
> + err = -ENODEV;
> + goto out;
> + }
> +
> + err = register_candev(dev);
> +
> + out:
> + /* disable core and turn off clocks */
> + flexcan_chip_disable(priv);
> + clk_disable(priv->clk);
> +
> + return err;
> +}
> +
> +static void __devexit unregister_flexcandev(struct net_device *dev)
> +{
> + unregister_candev(dev);
> +}
> +
> +static int __devinit flexcan_probe(struct platform_device *pdev)
> +{
> + struct net_device *dev;
> + struct flexcan_priv *priv;
> + struct resource *mem;
> + struct clk *clk;
> + void __iomem *base;
> + resource_size_t mem_size;
> + int err, irq;
> +
> + clk = clk_get(&pdev->dev, NULL);
> + if (IS_ERR(clk)) {
> + dev_err(&pdev->dev, "no clock defined\n");
> + err = PTR_ERR(clk);
> + goto failed_clock;
> + }
> +
> + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + irq = platform_get_irq(pdev, 0);
> + if (!mem || irq <= 0) {
> + err = -ENODEV;
> + goto failed_get;
> + }
> +
> + mem_size = resource_size(mem);
> + if (!request_mem_region(mem->start, mem_size, pdev->name)) {
> + err = -EBUSY;
> + goto failed_req;
> + }
> +
> + base = ioremap(mem->start, mem_size);
> + if (!base) {
> + err = -ENOMEM;
> + goto failed_map;
> + }
> +
> + dev = alloc_candev(sizeof(struct flexcan_priv), 0);
> + if (!dev) {
> + err = -ENOMEM;
> + goto failed_alloc;
> + }
> +
> + dev->netdev_ops = &flexcan_netdev_ops;
> + dev->irq = irq;
> + dev->flags |= IFF_ECHO; /* we support local echo in hardware */
> +
> + priv = netdev_priv(dev);
> + priv->can.clock.freq = clk_get_rate(clk);
> + priv->can.bittiming_const = &flexcan_bittiming_const;
> + priv->can.do_set_mode = flexcan_set_mode;
> + priv->can.do_get_berr_counter = flexcan_get_berr_counter;
> + priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
> + CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_3_SAMPLES;
> + priv->base = base;
> + priv->dev = dev;
> + priv->clk = clk;
> + priv->pdata = pdev->dev.platform_data;
> +
> + netif_napi_add(dev, &priv->napi, flexcan_poll, FLEXCAN_NAPI_WEIGHT);
> +
> + dev_set_drvdata(&pdev->dev, dev);
> + SET_NETDEV_DEV(dev, &pdev->dev);
> +
> + err = register_flexcandev(dev);
> + if (err) {
> + dev_err(&pdev->dev, "registering netdev failed\n");
> + goto failed_register;
> + }
> +
> + dev_info(&pdev->dev, "device registered (reg_base=%p, irq=%d)\n",
> + priv->base, dev->irq);
> +
> + return 0;
> +
> + failed_register:
> + free_candev(dev);
> + failed_alloc:
> + iounmap(base);
> + failed_map:
> + release_mem_region(mem->start, mem_size);
> + failed_req:
> + clk_put(clk);
> + failed_get:
> + failed_clock:
> + return err;
> +}
> +
> +static int __devexit flexcan_remove(struct platform_device *pdev)
> +{
> + struct net_device *dev = platform_get_drvdata(pdev);
> + struct flexcan_priv *priv = netdev_priv(dev);
> + struct resource *mem;
> +
> + unregister_flexcandev(dev);
> + platform_set_drvdata(pdev, NULL);
> + free_candev(dev);
> + iounmap(priv->base);
> +
> + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + release_mem_region(mem->start, resource_size(mem));
> +
> + clk_put(priv->clk);
> +
> + return 0;
> +}
> +
> +static struct platform_driver flexcan_driver = {
> + .driver.name = DRV_NAME,
> + .probe = flexcan_probe,
> + .remove = __devexit_p(flexcan_remove),
> +};
> +
> +static int __init flexcan_init(void)
> +{
> + pr_info("%s netdevice driver\n", DRV_NAME);
> + return platform_driver_register(&flexcan_driver);
> +}
> +
> +static void __exit flexcan_exit(void)
> +{
> + platform_driver_unregister(&flexcan_driver);
> + pr_info("%s: driver removed\n", DRV_NAME);
> +}
> +
> +module_init(flexcan_init);
> +module_exit(flexcan_exit);
> +
> +MODULE_AUTHOR("Sascha Hauer <kernel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>, "
> + "Marc Kleine-Budde <kernel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>");
> +MODULE_LICENSE("GPL v2");
> +MODULE_DESCRIPTION("CAN port driver for flexcan based chip");
> diff --git a/include/linux/can/platform/flexcan.h b/include/linux/can/platform/flexcan.h
> new file mode 100644
> index 0000000..72b713a
> --- /dev/null
> +++ b/include/linux/can/platform/flexcan.h
> @@ -0,0 +1,20 @@
> +/*
> + * Copyright (C) 2010 Marc Kleine-Budde <kernel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
> + *
> + * This file is released under the GPLv2
> + *
> + */
> +
> +#ifndef __CAN_PLATFORM_FLEXCAN_H
> +#define __CAN_PLATFORM_FLEXCAN_H
> +
> +/**
> + * struct flexcan_platform_data - flex CAN controller platform data
> + * @transceiver_enable: - called to power on/off the transceiver
> + *
> + */
> +struct flexcan_platform_data {
> + void (*transceiver_switch)(int enable);
> +};
> +
> +#endif /* __CAN_PLATFORM_FLEXCAN_H */
Wolfgang.
^ permalink raw reply
* [PATCH 03/25] atm: Convert pci_table entries to PCI_VDEVICE (if PCI_ANY_ID is used)
From: Peter Huewe @ 2010-07-15 18:38 UTC (permalink / raw)
To: Kernel Janitors
Cc: Chas Williams, David S. Miller, Ben Hutchings, Tejun Heo,
linux-atm-general, netdev, linux-kernel
From: Peter Huewe <peterhuewe@gmx.de>
This patch converts pci_table entries, where .subvendor=PCI_ANY_ID and
.subdevice=PCI_ANY_ID, .class=0 and .class_mask=0, to use the
PCI_VDEVICE macro, and thus improves readability.
Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
---
drivers/atm/ambassador.c | 6 ++----
1 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c
index 9d18644..a33896a 100644
--- a/drivers/atm/ambassador.c
+++ b/drivers/atm/ambassador.c
@@ -2371,10 +2371,8 @@ MODULE_PARM_DESC(pci_lat, "PCI latency in bus cycles");
/********** module entry **********/
static struct pci_device_id amb_pci_tbl[] = {
- { PCI_VENDOR_ID_MADGE, PCI_DEVICE_ID_MADGE_AMBASSADOR, PCI_ANY_ID, PCI_ANY_ID,
- 0, 0, 0 },
- { PCI_VENDOR_ID_MADGE, PCI_DEVICE_ID_MADGE_AMBASSADOR_BAD, PCI_ANY_ID, PCI_ANY_ID,
- 0, 0, 0 },
+ { PCI_VDEVICE(MADGE, PCI_DEVICE_ID_MADGE_AMBASSADOR), 0 },
+ { PCI_VDEVICE(MADGE, PCI_DEVICE_ID_MADGE_AMBASSADOR_BAD), 0 },
{ 0, }
};
--
1.7.1
^ permalink raw reply related
* Re: [PATCH] vhost-net: avoid flush under lock
From: Sridhar Samudrala @ 2010-07-15 18:17 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: David S. Miller, Arnd Bergmann, Paul E. McKenney, kvm,
virtualization, netdev, linux-kernel
In-Reply-To: <20100715121912.GA7176@redhat.com>
On Thu, 2010-07-15 at 15:19 +0300, Michael S. Tsirkin wrote:
> We flush under vq mutex when changing backends.
> This creates a deadlock as workqueue being flushed
> needs this lock as well.
>
> https://bugzilla.redhat.com/show_bug.cgi?id=612421
>
> Drop the vq mutex before flush: we have the device mutex
> which is sufficient to prevent another ioctl from touching
> the vq.
Why do we need to flush the vq when trying to set the backend and
we find that it is already set. Is this just an optimization?
Thanks
Sridhar
>
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> ---
> drivers/vhost/net.c | 5 +++++
> 1 files changed, 5 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
> index 28d7786..50df58e6 100644
> --- a/drivers/vhost/net.c
> +++ b/drivers/vhost/net.c
> @@ -534,11 +534,16 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
> rcu_assign_pointer(vq->private_data, sock);
> vhost_net_enable_vq(n, vq);
> done:
> + mutex_unlock(&vq->mutex);
> +
> if (oldsock) {
> vhost_net_flush_vq(n, index);
> fput(oldsock->file);
> }
>
> + mutex_unlock(&n->dev.mutex);
> + return 0;
> +
> err_vq:
> mutex_unlock(&vq->mutex);
> err:
^ permalink raw reply
* Re: [PATCHv4] netfilter: add CHECKSUM target
From: Michael S. Tsirkin @ 2010-07-15 17:42 UTC (permalink / raw)
To: Patrick McHardy
Cc: Daniel P. Berrange, Jes Sorensen, David S. Miller, Jan Engelhardt,
Randy Dunlap, netfilter-devel, netfilter, coreteam, linux-kernel,
netdev
In-Reply-To: <4C3F27A2.3030207@trash.net>
On Thu, Jul 15, 2010 at 05:22:10PM +0200, Patrick McHardy wrote:
> Am 15.07.2010 13:52, schrieb Michael S. Tsirkin:
> > This adds a `CHECKSUM' target, which can be used in the iptables mangle
> > table.
> >
> > You can use this target to compute and fill in the checksum in
> > a packet that lacks a checksum. This is particularly useful,
> > if you need to work around old applications such as dhcp clients,
> > that do not work well with checksum offloads, but don't want to
> > disable checksum offload in your device.
> >
> > The problem happens in the field with virtualized applications.
> > For reference, see Red Hat bz 605555, as well as
> > http://www.spinics.net/lists/kvm/msg37660.html
> >
> > Typical expected use (helps old dhclient binary running in a VM):
> > iptables -A POSTROUTING -t mangle -p udp --dport bootpc \
> > -j CHECKSUM --checksum-fill
> >
> > Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> > Includes fixes by Jan Engelhardt <jengelh@medozas.de>
>
> Applied, thanks Michael.
I forgot to export the header. And once I added it, I got warning
on header_check, so here's a fixup. Sorry about the noise.
netfilter: correct CHECKSUM header and export it
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
--
diff --git a/include/linux/netfilter/Kbuild b/include/linux/netfilter/Kbuild
index 48767cd..0c3098f 100644
--- a/include/linux/netfilter/Kbuild
+++ b/include/linux/netfilter/Kbuild
@@ -3,6 +3,7 @@ header-y += nf_conntrack_tuple_common.h
header-y += nfnetlink_conntrack.h
header-y += nfnetlink_log.h
header-y += nfnetlink_queue.h
+header-y += xt_CHECKSUM.h
header-y += xt_CLASSIFY.h
header-y += xt_CONNMARK.h
header-y += xt_CONNSECMARK.h
diff --git a/include/linux/netfilter/xt_CHECKSUM.h b/include/linux/netfilter/xt_CHECKSUM.h
index 3b4fb77..9a2e466 100644
--- a/include/linux/netfilter/xt_CHECKSUM.h
+++ b/include/linux/netfilter/xt_CHECKSUM.h
@@ -6,8 +6,10 @@
*
* This software is distributed under GNU GPL v2, 1991
*/
-#ifndef _IPT_CHECKSUM_TARGET_H
-#define _IPT_CHECKSUM_TARGET_H
+#ifndef _XT_CHECKSUM_TARGET_H
+#define _XT_CHECKSUM_TARGET_H
+
+#include <linux/types.h>
#define XT_CHECKSUM_OP_FILL 0x01 /* fill in checksum in IP header */
@@ -15,4 +17,4 @@ struct xt_CHECKSUM_info {
__u8 operation; /* bitset of operations */
};
-#endif /* _IPT_CHECKSUM_TARGET_H */
+#endif /* _XT_CHECKSUM_TARGET_H */
^ permalink raw reply related
* Re: Raise initial congestion window size / speedup slow start?
From: Jerry Chu @ 2010-07-15 17:36 UTC (permalink / raw)
To: Ed W
Cc: Tom Herbert, Hagen Paul Pfeifer, Rick Jones, David Miller,
davidsen, linux-kernel, netdev, Nandita Dukkipati
In-Reply-To: <4C3EBD51.80406@wildgooses.com>
On Thu, Jul 15, 2010 at 12:48 AM, Ed W <lists@wildgooses.com> wrote:
>
> On 15/07/2010 05:12, Tom Herbert wrote:
>>
>> There is an Internet draft
>> (http://datatracker.ietf.org/doc/draft-hkchu-tcpm-initcwnd/) on
>> raising the default Initial Congestion window to 10 segments, as well
>> as a SIGCOMM paper (http://ccr.sigcomm.org/online/?q=node/621).
>>
>
> You guys have obviously done a lot of work on this, however, it seems that there is a case for introducing some heuristics into the choice of init cwnd as well as offering the option to go larger? An initial size of 10 packets is just another magic number that obviously works with the median bandwidth delay product on today's networks - can we not do better still?
>
> Seems like a bunch of clever folks have already suggested tweaks to the steady stage congestion avoidance, but so far everyone is afraid to touch the early stage heuristics?
This is because there is not enough info for deriving any heuristic.
For initcwnd one is constrained to
only info from 3WHS. This includes a rough estimate of RTT plus all
the bits in the SYN/SYN-ACK
headers. I'm assuming a stateless approach. We've tried a stateful
solution (i.e., seeding initcwnd from
past history) but found its complexity outweigh the gain.
(See http://www.ietf.org/proceedings/77/slides/tcpm-4.pdf)
>
> Also would you guys not benefit from wider deployment of ECN? Can you not help find some ways that deployment could be increased? At present there are big warnings all over the option that it causes some problems, but there is no quantification of how much and really whether this warning is still appropriate?
That will add yet another hoop for us to jump over. Also I'm not sure
a couple of bits are sufficient for a
guesstimate of what initcwnd ought to be.
Our reasoning is simple - there has been tremendous b/w growth since
rfc2414 was published. Even the
lowest common denominator (i.e., dialup links) has moved from 9.6Kbps
to 56Kbps. That's a six fold
increase. If you believe initcwnd should grow proportionally to the
buffer sizes in access links, and the
buffer sizes grows proportionally to b/w, then the initcwnd outght to
be 3*6 = 18 today.
We chose a modest increase (10) with the hope to expedite the
standardization process (and would
certainly appreciate helps from folks on this list). 10 is very
conservative considering many deployment
has gone beyond 3, including Linux stack, which allows one additional
pkt if it's the last data pkt.
Longer term it will be nice to find a way to get rid of this fixed,
somewhat arbitrary initcwnd. Mark
Allman's JumpStart is one idea, but it'd be a much longer route.
Jerry
>
> Ed W
>
^ permalink raw reply
* Re: [PATCH RFC] act_cpu: packet distributing
From: Eric Dumazet @ 2010-07-15 16:54 UTC (permalink / raw)
To: hadi; +Cc: Changli Gao, David S. Miller, Patrick McHardy, Tom Herbert,
netdev
In-Reply-To: <1279198139.4510.710.camel@bigi>
Le jeudi 15 juillet 2010 à 08:48 -0400, jamal a écrit :
> On Wed, 2010-07-14 at 12:17 +0800, Changli Gao wrote:
>
> > Thanks, I'll try. It is a write critical section, and for me it is
> > difficult to convert this lock to RCU. Could you show me some
> > examples?
>
> RCU maybe a little trickier here Eric. Actions could be shared i.e.
> example, it is possible to have a policer action restricting rates for a
> group of flows across multiple netdevices etc. Since action stats get
> written to by different CPUs concurrently. It could be probably done if
> one was to implement per-cpu stats which get summed-up when user space
> asks.
It's certainly tricky, but is act_cpu useful in its current shape, based
on an infrastructure that had to use a lock because of exact
rates/accounting ?
I dont understand how distributing packets to different cpus, if going
through a central lock can be an improvement. Changli patches are most
of the time not documented, and no performance data is provided.
Even if we solve this locking problem, using percpu variables, act_cpu
hits another problem :
The socket refcount, taken by the 'master' cpu, and released by the
consumer cpu.
RFS provides sort of a lazy flow-based distribution without central lock
or cache line ping pongs. Why Changli dont use this, we dont know yet.
^ permalink raw reply
* Re: multiqueue, skb_get_queue_mapping() and netdev_get_tx_queue()
From: Eldon Koyle @ 2010-07-15 16:22 UTC (permalink / raw)
To: netdev
In-Reply-To: <20100714231352.GA32397@esk.cs.usu.edu>
On Jul 14 17:13-0600, Eldon Koyle wrote:
> It looks like there is a potential for an out of bounds index anywhere
> skb_get_queue_mapping(skb) (which just returns skb->queue_mapping) is
> used to get an index for netdev_get_tx_queue() (and probably other
> places) on a device with multiple rx/tx queues.
Looking more closely, it looks like skb->queue_mapping is treated
differently between rx and tx. In net/core/dev.c in dev_pick_tx, it
uses skb_tx_hash to get the tx queue it should use and then does:
skb_set_queue_mapping(skb, queue_index);
return netdev_get_tx_queue(dev, queue_index);
Sorry for the noise.
--
Eldon Koyle
--
He who renders warfare fatal to all engaged in it will be the greatest
benefactor the world has yet known.
-- Sir Richard Burton
^ permalink raw reply
* Re: Question about way that NICs deliver packets to the kernel
From: Stephen Hemminger @ 2010-07-15 15:59 UTC (permalink / raw)
To: Ben Hutchings; +Cc: Junchang Wang, romieu, netdev
In-Reply-To: <1279204417.2118.12.camel@achroite.uk.solarflarecom.com>
On Thu, 15 Jul 2010 15:33:37 +0100
Ben Hutchings <bhutchings@solarflare.com> wrote:
> On Thu, 2010-07-15 at 22:24 +0800, Junchang Wang wrote:
> > Hi list,
> > My understand of the way that NICs deliver packets to the kernel is
> > as follows. Correct me if any of this is wrong. Thanks.
> >
> > 1) The device buffer is fixed. When the kernel is acknowledged arrival of a
> > new packet, it dynamically allocate a new skb and copy the packet into it.
> > For example, 8139too.
> >
> > 2) The device buffer is mapped by streaming DMA. When the kernel is
> > acknowledged arrival of a new packet, it unmaps the region previously mapped.
> > Obviously, there is NO memcpy operation. Additional cost is streaming DMA
> > map/unmap operations. For example, e100 and e1000.
> >
> > Here comes my question:
> > 1) Is there a principle indicating which one is better? Is streaming DMA
> > map/unmap operations more expensive than memcpy operation?
>
> DMA should result in lower CPU usage and higher maximum performance.
>
> > 2) Why does r8169 bias towards the first approach even if it support both? I
> > convert r8169 to the second one and get a 5% performance boost. Below is result
> > running netperf TCP_STREAM test with 1.6K byte packet length.
> > scheme 1 scheme 2 Imp.
> > r8169 683M 718M 5%
> [...]
>
> You should also compare the CPU usage.
Also many drivers copy small receives into a new buffer
which saves space and often gives better performance.
^ permalink raw reply
* Re: [PATCHv4] extensions: libxt_CHECKSUM extension
From: Patrick McHardy @ 2010-07-15 15:24 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: Daniel P. Berrange, Jes Sorensen, David S. Miller, Jan Engelhardt,
Randy Dunlap, netfilter-devel, netfilter, coreteam, linux-kernel,
netdev
In-Reply-To: <20100715115229.GB6737@redhat.com>
Am 15.07.2010 13:52, schrieb Michael S. Tsirkin:
> This adds a `CHECKSUM' target, which can be used in the iptables mangle
> table.
>
> You can use this target to compute and fill in the checksum in
> a packet that lacks a checksum. This is particularly useful,
> if you need to work around old applications such as dhcp clients,
> that do not work well with checksum offloads, but don't want to disable
> checksum offload in your device.
>
> The problem happens in the field with virtualized applications.
> For reference, see Red Hat bz 605555, as well as
> http://www.spinics.net/lists/kvm/msg37660.html
>
> Typical expected use (helps old dhclient binary running in a VM):
> iptables -A POSTROUTING -t mangle -p udp --dport bootpc \
> -j CHECKSUM --checksum-fill
Applied to iptables-next, thanks.
^ permalink raw reply
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