diff options
author | Francois Romieu <romieu@fr.zoreil.com> | 2008-07-10 18:05:17 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-07-11 01:10:15 -0400 |
commit | 28133176082d9bcafb5958b8fac80943e51d5eda (patch) | |
tree | 6b04bba488f4484769f2d92413253496e5a5729c /drivers/net/via-velocity.c | |
parent | 8ac53afccf7ab383fd97db8910117ae7892c72a7 (diff) |
via-velocity: move residual free rx descriptors count register update
Updates of the RBRDU have two different meanings depending on their
context:
1. the receiving process has not started - the value which is written
into the RBRDU register is supposed to be the free rx descriptors
count (rounded to a multiple of 4)
2. the receiving process is running - the value increments the count
above (sic)
The update is currently issued deep inside the rx replenish chain (see
velocity_give_many_rx_descs).
Let's propagate enough information to the caller so that the rx
replenish functions do not depend on hardware any more.
It is needed to perform the Rx/Tx buffers housekeeping when MTU changes.
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/net/via-velocity.c')
-rw-r--r-- | drivers/net/via-velocity.c | 28 |
1 files changed, 14 insertions, 14 deletions
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index 86b256cbeaf3..086d69c19920 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c | |||
@@ -1155,7 +1155,7 @@ static void velocity_free_rings(struct velocity_info *vptr) | |||
1155 | pci_free_consistent(vptr->pdev, size, vptr->rd_ring, vptr->rd_pool_dma); | 1155 | pci_free_consistent(vptr->pdev, size, vptr->rd_ring, vptr->rd_pool_dma); |
1156 | } | 1156 | } |
1157 | 1157 | ||
1158 | static inline void velocity_give_many_rx_descs(struct velocity_info *vptr) | 1158 | static void velocity_give_many_rx_descs(struct velocity_info *vptr) |
1159 | { | 1159 | { |
1160 | struct mac_regs __iomem *regs = vptr->mac_regs; | 1160 | struct mac_regs __iomem *regs = vptr->mac_regs; |
1161 | int avail, dirty, unusable; | 1161 | int avail, dirty, unusable; |
@@ -1182,7 +1182,7 @@ static inline void velocity_give_many_rx_descs(struct velocity_info *vptr) | |||
1182 | 1182 | ||
1183 | static int velocity_rx_refill(struct velocity_info *vptr) | 1183 | static int velocity_rx_refill(struct velocity_info *vptr) |
1184 | { | 1184 | { |
1185 | int dirty = vptr->rd_dirty, done = 0, ret = 0; | 1185 | int dirty = vptr->rd_dirty, done = 0; |
1186 | 1186 | ||
1187 | do { | 1187 | do { |
1188 | struct rx_desc *rd = vptr->rd_ring + dirty; | 1188 | struct rx_desc *rd = vptr->rd_ring + dirty; |
@@ -1192,8 +1192,7 @@ static int velocity_rx_refill(struct velocity_info *vptr) | |||
1192 | break; | 1192 | break; |
1193 | 1193 | ||
1194 | if (!vptr->rd_info[dirty].skb) { | 1194 | if (!vptr->rd_info[dirty].skb) { |
1195 | ret = velocity_alloc_rx_buf(vptr, dirty); | 1195 | if (velocity_alloc_rx_buf(vptr, dirty) < 0) |
1196 | if (ret < 0) | ||
1197 | break; | 1196 | break; |
1198 | } | 1197 | } |
1199 | done++; | 1198 | done++; |
@@ -1203,10 +1202,9 @@ static int velocity_rx_refill(struct velocity_info *vptr) | |||
1203 | if (done) { | 1202 | if (done) { |
1204 | vptr->rd_dirty = dirty; | 1203 | vptr->rd_dirty = dirty; |
1205 | vptr->rd_filled += done; | 1204 | vptr->rd_filled += done; |
1206 | velocity_give_many_rx_descs(vptr); | ||
1207 | } | 1205 | } |
1208 | 1206 | ||
1209 | return ret; | 1207 | return done; |
1210 | } | 1208 | } |
1211 | 1209 | ||
1212 | /** | 1210 | /** |
@@ -1219,25 +1217,27 @@ static int velocity_rx_refill(struct velocity_info *vptr) | |||
1219 | 1217 | ||
1220 | static int velocity_init_rd_ring(struct velocity_info *vptr) | 1218 | static int velocity_init_rd_ring(struct velocity_info *vptr) |
1221 | { | 1219 | { |
1222 | int ret; | ||
1223 | int mtu = vptr->dev->mtu; | 1220 | int mtu = vptr->dev->mtu; |
1221 | int ret = -ENOMEM; | ||
1224 | 1222 | ||
1225 | vptr->rx_buf_sz = (mtu <= ETH_DATA_LEN) ? PKT_BUF_SZ : mtu + 32; | 1223 | vptr->rx_buf_sz = (mtu <= ETH_DATA_LEN) ? PKT_BUF_SZ : mtu + 32; |
1226 | 1224 | ||
1227 | vptr->rd_info = kcalloc(vptr->options.numrx, | 1225 | vptr->rd_info = kcalloc(vptr->options.numrx, |
1228 | sizeof(struct velocity_rd_info), GFP_KERNEL); | 1226 | sizeof(struct velocity_rd_info), GFP_KERNEL); |
1229 | if (!vptr->rd_info) | 1227 | if (!vptr->rd_info) |
1230 | return -ENOMEM; | 1228 | goto out; |
1231 | 1229 | ||
1232 | vptr->rd_filled = vptr->rd_dirty = vptr->rd_curr = 0; | 1230 | vptr->rd_filled = vptr->rd_dirty = vptr->rd_curr = 0; |
1233 | 1231 | ||
1234 | ret = velocity_rx_refill(vptr); | 1232 | if (velocity_rx_refill(vptr) != vptr->options.numrx) { |
1235 | if (ret < 0) { | ||
1236 | VELOCITY_PRT(MSG_LEVEL_ERR, KERN_ERR | 1233 | VELOCITY_PRT(MSG_LEVEL_ERR, KERN_ERR |
1237 | "%s: failed to allocate RX buffer.\n", vptr->dev->name); | 1234 | "%s: failed to allocate RX buffer.\n", vptr->dev->name); |
1238 | velocity_free_rd_ring(vptr); | 1235 | velocity_free_rd_ring(vptr); |
1236 | goto out; | ||
1239 | } | 1237 | } |
1240 | 1238 | ||
1239 | ret = 0; | ||
1240 | out: | ||
1241 | return ret; | 1241 | return ret; |
1242 | } | 1242 | } |
1243 | 1243 | ||
@@ -1412,10 +1412,8 @@ static int velocity_rx_srv(struct velocity_info *vptr, int status) | |||
1412 | 1412 | ||
1413 | vptr->rd_curr = rd_curr; | 1413 | vptr->rd_curr = rd_curr; |
1414 | 1414 | ||
1415 | if (works > 0 && velocity_rx_refill(vptr) < 0) { | 1415 | if ((works > 0) && (velocity_rx_refill(vptr) > 0)) |
1416 | VELOCITY_PRT(MSG_LEVEL_ERR, KERN_ERR | 1416 | velocity_give_many_rx_descs(vptr); |
1417 | "%s: rx buf allocation failure\n", vptr->dev->name); | ||
1418 | } | ||
1419 | 1417 | ||
1420 | VAR_USED(stats); | 1418 | VAR_USED(stats); |
1421 | return works; | 1419 | return works; |
@@ -1877,6 +1875,8 @@ static int velocity_open(struct net_device *dev) | |||
1877 | /* Ensure chip is running */ | 1875 | /* Ensure chip is running */ |
1878 | pci_set_power_state(vptr->pdev, PCI_D0); | 1876 | pci_set_power_state(vptr->pdev, PCI_D0); |
1879 | 1877 | ||
1878 | velocity_give_many_rx_descs(vptr); | ||
1879 | |||
1880 | velocity_init_registers(vptr, VELOCITY_INIT_COLD); | 1880 | velocity_init_registers(vptr, VELOCITY_INIT_COLD); |
1881 | 1881 | ||
1882 | ret = request_irq(vptr->pdev->irq, &velocity_intr, IRQF_SHARED, | 1882 | ret = request_irq(vptr->pdev->irq, &velocity_intr, IRQF_SHARED, |