Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 134685
b: refs/heads/master
c: 4545a3f
h: refs/heads/master
i:
  134683: b2407c9
v: v3
  • Loading branch information
Ron Mercer authored and David S. Miller committed Feb 25, 2009
1 parent f93f3ca commit fe65df2
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 112 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 49f2186d36a88ae6f7dd8261aff2cf80409af28d
refs/heads/master: 4545a3f2765bb7d2d93468a8ffa578ac87a2c5c7
170 changes: 59 additions & 111 deletions trunk/drivers/net/qlge/qlge_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2105,47 +2105,6 @@ static void ql_free_lbq_buffers(struct ql_adapter *qdev, struct rx_ring *rx_ring
}
}

/*
* Allocate and map a page for each element of the lbq.
*/
static int ql_alloc_lbq_buffers(struct ql_adapter *qdev,
struct rx_ring *rx_ring)
{
int i;
struct bq_desc *lbq_desc;
u64 map;
__le64 *bq = rx_ring->lbq_base;

for (i = 0; i < rx_ring->lbq_len; i++) {
lbq_desc = &rx_ring->lbq[i];
memset(lbq_desc, 0, sizeof(lbq_desc));
lbq_desc->addr = bq;
lbq_desc->index = i;
lbq_desc->p.lbq_page = alloc_page(GFP_ATOMIC);
if (unlikely(!lbq_desc->p.lbq_page)) {
QPRINTK(qdev, IFUP, ERR, "failed alloc_page().\n");
goto mem_error;
} else {
map = pci_map_page(qdev->pdev,
lbq_desc->p.lbq_page,
0, PAGE_SIZE, PCI_DMA_FROMDEVICE);
if (pci_dma_mapping_error(qdev->pdev, map)) {
QPRINTK(qdev, IFUP, ERR,
"PCI mapping failed.\n");
goto mem_error;
}
pci_unmap_addr_set(lbq_desc, mapaddr, map);
pci_unmap_len_set(lbq_desc, maplen, PAGE_SIZE);
*lbq_desc->addr = cpu_to_le64(map);
}
bq++;
}
return 0;
mem_error:
ql_free_lbq_buffers(qdev, rx_ring);
return -ENOMEM;
}

static void ql_free_sbq_buffers(struct ql_adapter *qdev, struct rx_ring *rx_ring)
{
int i;
Expand All @@ -2168,63 +2127,72 @@ static void ql_free_sbq_buffers(struct ql_adapter *qdev, struct rx_ring *rx_ring
}
}

/* Allocate and map an skb for each element of the sbq. */
static int ql_alloc_sbq_buffers(struct ql_adapter *qdev,
/* Free all large and small rx buffers associated
* with the completion queues for this device.
*/
static void ql_free_rx_buffers(struct ql_adapter *qdev)
{
int i;
struct rx_ring *rx_ring;

for (i = 0; i < qdev->rx_ring_count; i++) {
rx_ring = &qdev->rx_ring[i];
if (rx_ring->lbq)
ql_free_lbq_buffers(qdev, rx_ring);
if (rx_ring->sbq)
ql_free_sbq_buffers(qdev, rx_ring);
}
}

static void ql_alloc_rx_buffers(struct ql_adapter *qdev)
{
struct rx_ring *rx_ring;
int i;

for (i = 0; i < qdev->rx_ring_count; i++) {
rx_ring = &qdev->rx_ring[i];
if (rx_ring->type != TX_Q)
ql_update_buffer_queues(qdev, rx_ring);
}
}

static void ql_init_lbq_ring(struct ql_adapter *qdev,
struct rx_ring *rx_ring)
{
int i;
struct bq_desc *lbq_desc;
__le64 *bq = rx_ring->lbq_base;

memset(rx_ring->lbq, 0, rx_ring->lbq_len * sizeof(struct bq_desc));
for (i = 0; i < rx_ring->lbq_len; i++) {
lbq_desc = &rx_ring->lbq[i];
memset(lbq_desc, 0, sizeof(*lbq_desc));
lbq_desc->index = i;
lbq_desc->addr = bq;
bq++;
}
}

static void ql_init_sbq_ring(struct ql_adapter *qdev,
struct rx_ring *rx_ring)
{
int i;
struct bq_desc *sbq_desc;
struct sk_buff *skb;
u64 map;
__le64 *bq = rx_ring->sbq_base;

memset(rx_ring->sbq, 0, rx_ring->sbq_len * sizeof(struct bq_desc));
for (i = 0; i < rx_ring->sbq_len; i++) {
sbq_desc = &rx_ring->sbq[i];
memset(sbq_desc, 0, sizeof(sbq_desc));
memset(sbq_desc, 0, sizeof(*sbq_desc));
sbq_desc->index = i;
sbq_desc->addr = bq;
skb = netdev_alloc_skb(qdev->ndev, rx_ring->sbq_buf_size);
if (unlikely(!skb)) {
/* Better luck next round */
QPRINTK(qdev, IFUP, ERR,
"small buff alloc failed for %d bytes at index %d.\n",
rx_ring->sbq_buf_size, i);
goto mem_err;
}
skb_reserve(skb, QLGE_SB_PAD);
sbq_desc->p.skb = skb;
/*
* Map only half the buffer. Because the
* other half may get some data copied to it
* when the completion arrives.
*/
map = pci_map_single(qdev->pdev,
skb->data,
rx_ring->sbq_buf_size / 2,
PCI_DMA_FROMDEVICE);
if (pci_dma_mapping_error(qdev->pdev, map)) {
QPRINTK(qdev, IFUP, ERR, "PCI mapping failed.\n");
goto mem_err;
}
pci_unmap_addr_set(sbq_desc, mapaddr, map);
pci_unmap_len_set(sbq_desc, maplen, rx_ring->sbq_buf_size / 2);
*sbq_desc->addr = cpu_to_le64(map);
bq++;
}
return 0;
mem_err:
ql_free_sbq_buffers(qdev, rx_ring);
return -ENOMEM;
}

static void ql_free_rx_resources(struct ql_adapter *qdev,
struct rx_ring *rx_ring)
{
if (rx_ring->sbq_len)
ql_free_sbq_buffers(qdev, rx_ring);
if (rx_ring->lbq_len)
ql_free_lbq_buffers(qdev, rx_ring);

/* Free the small buffer queue. */
if (rx_ring->sbq_base) {
pci_free_consistent(qdev->pdev,
Expand Down Expand Up @@ -2302,11 +2270,7 @@ static int ql_alloc_rx_resources(struct ql_adapter *qdev,
goto err_mem;
}

if (ql_alloc_sbq_buffers(qdev, rx_ring)) {
QPRINTK(qdev, IFUP, ERR,
"Small buffer allocation failed.\n");
goto err_mem;
}
ql_init_sbq_ring(qdev, rx_ring);
}

if (rx_ring->lbq_len) {
Expand Down Expand Up @@ -2334,14 +2298,7 @@ static int ql_alloc_rx_resources(struct ql_adapter *qdev,
goto err_mem;
}

/*
* Allocate the buffers.
*/
if (ql_alloc_lbq_buffers(qdev, rx_ring)) {
QPRINTK(qdev, IFUP, ERR,
"Large buffer allocation failed.\n");
goto err_mem;
}
ql_init_lbq_ring(qdev, rx_ring);
}

return 0;
Expand Down Expand Up @@ -2489,10 +2446,10 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring)
bq_len = (rx_ring->lbq_len == 65536) ? 0 :
(u16) rx_ring->lbq_len;
cqicb->lbq_len = cpu_to_le16(bq_len);
rx_ring->lbq_prod_idx = rx_ring->lbq_len - 16;
rx_ring->lbq_prod_idx = 0;
rx_ring->lbq_curr_idx = 0;
rx_ring->lbq_clean_idx = rx_ring->lbq_prod_idx;
rx_ring->lbq_free_cnt = 16;
rx_ring->lbq_clean_idx = 0;
rx_ring->lbq_free_cnt = rx_ring->lbq_len;
}
if (rx_ring->sbq_len) {
cqicb->flags |= FLAGS_LS; /* Load sbq values */
Expand All @@ -2504,10 +2461,10 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring)
bq_len = (rx_ring->sbq_len == 65536) ? 0 :
(u16) rx_ring->sbq_len;
cqicb->sbq_len = cpu_to_le16(bq_len);
rx_ring->sbq_prod_idx = rx_ring->sbq_len - 16;
rx_ring->sbq_prod_idx = 0;
rx_ring->sbq_curr_idx = 0;
rx_ring->sbq_clean_idx = rx_ring->sbq_prod_idx;
rx_ring->sbq_free_cnt = 16;
rx_ring->sbq_clean_idx = 0;
rx_ring->sbq_free_cnt = rx_ring->sbq_len;
}
switch (rx_ring->type) {
case TX_Q:
Expand Down Expand Up @@ -2560,17 +2517,6 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring)
QPRINTK(qdev, IFUP, ERR, "Failed to load CQICB.\n");
return err;
}
QPRINTK(qdev, IFUP, INFO, "Successfully loaded CQICB.\n");
/*
* Advance the producer index for the buffer queues.
*/
wmb();
if (rx_ring->lbq_len)
ql_write_db_reg(rx_ring->lbq_prod_idx,
rx_ring->lbq_prod_idx_db_reg);
if (rx_ring->sbq_len)
ql_write_db_reg(rx_ring->sbq_prod_idx,
rx_ring->sbq_prod_idx_db_reg);
return err;
}

Expand Down Expand Up @@ -3171,6 +3117,7 @@ static int ql_adapter_down(struct ql_adapter *qdev)

ql_tx_ring_clean(qdev);

ql_free_rx_buffers(qdev);
spin_lock(&qdev->hw_lock);
status = ql_adapter_reset(qdev);
if (status)
Expand All @@ -3193,6 +3140,7 @@ static int ql_adapter_up(struct ql_adapter *qdev)
}
spin_unlock(&qdev->hw_lock);
set_bit(QL_ADAPTER_UP, &qdev->flags);
ql_alloc_rx_buffers(qdev);
ql_enable_interrupts(qdev);
ql_enable_all_completion_interrupts(qdev);
if ((ql_read32(qdev, STS) & qdev->port_init)) {
Expand Down

0 comments on commit fe65df2

Please sign in to comment.