aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorstephen hemminger <shemminger@vyatta.com>2010-04-22 09:42:56 -0400
committerDavid S. Miller <davem@davemloft.net>2010-04-22 21:32:58 -0400
commitefe91932e79cfe59a562b70d8eb18049b36debc6 (patch)
treedade60807aa05f2b06b15321086487ee3f372cd7
parent286d1e7f73320be063a5f6af25d3d61c741065c2 (diff)
sky2: size status ring based on Tx/Rx ring
Sky2 status ring must be big enough to handle worst case number of status messages. It was being oversized (to handle dual port cards), and excessive number of tx ring entries were allowed. This patch reduces the footprint and makes sure the value is enough. Later patch to add RSS increases the number of possible Rx status elements. Signed-off-by: Stephen Hemminger <shemminger@vyatta.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/sky2.c35
-rw-r--r--drivers/net/sky2.h1
2 files changed, 20 insertions, 16 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 3a086d3a7cbf..4f83f111bb20 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -70,18 +70,15 @@
70 VLAN:GSO + CKSUM + Data + skb_frags * DMA */ 70 VLAN:GSO + CKSUM + Data + skb_frags * DMA */
71#define MAX_SKB_TX_LE (2 + (sizeof(dma_addr_t)/sizeof(u32))*(MAX_SKB_FRAGS+1)) 71#define MAX_SKB_TX_LE (2 + (sizeof(dma_addr_t)/sizeof(u32))*(MAX_SKB_FRAGS+1))
72#define TX_MIN_PENDING (MAX_SKB_TX_LE+1) 72#define TX_MIN_PENDING (MAX_SKB_TX_LE+1)
73#define TX_MAX_PENDING 4096 73#define TX_MAX_PENDING 1024
74#define TX_DEF_PENDING 127 74#define TX_DEF_PENDING 127
75 75
76#define STATUS_RING_SIZE 2048 /* 2 ports * (TX + 2*RX) */
77#define STATUS_LE_BYTES (STATUS_RING_SIZE*sizeof(struct sky2_status_le))
78#define TX_WATCHDOG (5 * HZ) 76#define TX_WATCHDOG (5 * HZ)
79#define NAPI_WEIGHT 64 77#define NAPI_WEIGHT 64
80#define PHY_RETRIES 1000 78#define PHY_RETRIES 1000
81 79
82#define SKY2_EEPROM_MAGIC 0x9955aabb 80#define SKY2_EEPROM_MAGIC 0x9955aabb
83 81
84
85#define RING_NEXT(x,s) (((x)+1) & ((s)-1)) 82#define RING_NEXT(x,s) (((x)+1) & ((s)-1))
86 83
87static const u32 default_msg = 84static const u32 default_msg =
@@ -2558,7 +2555,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)
2558 if (!(opcode & HW_OWNER)) 2555 if (!(opcode & HW_OWNER))
2559 break; 2556 break;
2560 2557
2561 hw->st_idx = RING_NEXT(hw->st_idx, STATUS_RING_SIZE); 2558 hw->st_idx = RING_NEXT(hw->st_idx, hw->st_size);
2562 2559
2563 port = le->css & CSS_LINK_BIT; 2560 port = le->css & CSS_LINK_BIT;
2564 dev = hw->dev[port]; 2561 dev = hw->dev[port];
@@ -3198,7 +3195,7 @@ static void sky2_reset(struct sky2_hw *hw)
3198 for (i = 0; i < hw->ports; i++) 3195 for (i = 0; i < hw->ports; i++)
3199 sky2_gmac_reset(hw, i); 3196 sky2_gmac_reset(hw, i);
3200 3197
3201 memset(hw->st_le, 0, STATUS_LE_BYTES); 3198 memset(hw->st_le, 0, hw->st_size * sizeof(struct sky2_status_le));
3202 hw->st_idx = 0; 3199 hw->st_idx = 0;
3203 3200
3204 sky2_write32(hw, STAT_CTRL, SC_STAT_RST_SET); 3201 sky2_write32(hw, STAT_CTRL, SC_STAT_RST_SET);
@@ -3208,7 +3205,7 @@ static void sky2_reset(struct sky2_hw *hw)
3208 sky2_write32(hw, STAT_LIST_ADDR_HI, (u64) hw->st_dma >> 32); 3205 sky2_write32(hw, STAT_LIST_ADDR_HI, (u64) hw->st_dma >> 32);
3209 3206
3210 /* Set the list last index */ 3207 /* Set the list last index */
3211 sky2_write16(hw, STAT_LAST_IDX, STATUS_RING_SIZE - 1); 3208 sky2_write16(hw, STAT_LAST_IDX, hw->st_size - 1);
3212 3209
3213 sky2_write16(hw, STAT_TX_IDX_TH, 10); 3210 sky2_write16(hw, STAT_TX_IDX_TH, 10);
3214 sky2_write8(hw, STAT_FIFO_WM, 16); 3211 sky2_write8(hw, STAT_FIFO_WM, 16);
@@ -4256,12 +4253,13 @@ static int sky2_debug_show(struct seq_file *seq, void *v)
4256 napi_disable(&hw->napi); 4253 napi_disable(&hw->napi);
4257 last = sky2_read16(hw, STAT_PUT_IDX); 4254 last = sky2_read16(hw, STAT_PUT_IDX);
4258 4255
4256 seq_printf(seq, "Status ring %u\n", hw->st_size);
4259 if (hw->st_idx == last) 4257 if (hw->st_idx == last)
4260 seq_puts(seq, "Status ring (empty)\n"); 4258 seq_puts(seq, "Status ring (empty)\n");
4261 else { 4259 else {
4262 seq_puts(seq, "Status ring\n"); 4260 seq_puts(seq, "Status ring\n");
4263 for (idx = hw->st_idx; idx != last && idx < STATUS_RING_SIZE; 4261 for (idx = hw->st_idx; idx != last && idx < hw->st_size;
4264 idx = RING_NEXT(idx, STATUS_RING_SIZE)) { 4262 idx = RING_NEXT(idx, hw->st_size)) {
4265 const struct sky2_status_le *le = hw->st_le + idx; 4263 const struct sky2_status_le *le = hw->st_le + idx;
4266 seq_printf(seq, "[%d] %#x %d %#x\n", 4264 seq_printf(seq, "[%d] %#x %d %#x\n",
4267 idx, le->opcode, le->length, le->status); 4265 idx, le->opcode, le->length, le->status);
@@ -4689,15 +4687,17 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
4689 goto err_out_free_hw; 4687 goto err_out_free_hw;
4690 } 4688 }
4691 4689
4692 /* ring for status responses */
4693 hw->st_le = pci_alloc_consistent(pdev, STATUS_LE_BYTES, &hw->st_dma);
4694 if (!hw->st_le)
4695 goto err_out_iounmap;
4696
4697 err = sky2_init(hw); 4690 err = sky2_init(hw);
4698 if (err) 4691 if (err)
4699 goto err_out_iounmap; 4692 goto err_out_iounmap;
4700 4693
4694 /* ring for status responses */
4695 hw->st_size = hw->ports * roundup_pow_of_two(2*RX_MAX_PENDING + TX_MAX_PENDING);
4696 hw->st_le = pci_alloc_consistent(pdev, hw->st_size * sizeof(struct sky2_status_le),
4697 &hw->st_dma);
4698 if (!hw->st_le)
4699 goto err_out_reset;
4700
4701 dev_info(&pdev->dev, "Yukon-2 %s chip revision %d\n", 4701 dev_info(&pdev->dev, "Yukon-2 %s chip revision %d\n",
4702 sky2_name(hw->chip_id, buf1, sizeof(buf1)), hw->chip_rev); 4702 sky2_name(hw->chip_id, buf1, sizeof(buf1)), hw->chip_rev);
4703 4703
@@ -4771,8 +4771,10 @@ err_out_unregister:
4771err_out_free_netdev: 4771err_out_free_netdev:
4772 free_netdev(dev); 4772 free_netdev(dev);
4773err_out_free_pci: 4773err_out_free_pci:
4774 pci_free_consistent(pdev, hw->st_size * sizeof(struct sky2_status_le),
4775 hw->st_le, hw->st_dma);
4776err_out_reset:
4774 sky2_write8(hw, B0_CTST, CS_RST_SET); 4777 sky2_write8(hw, B0_CTST, CS_RST_SET);
4775 pci_free_consistent(pdev, STATUS_LE_BYTES, hw->st_le, hw->st_dma);
4776err_out_iounmap: 4778err_out_iounmap:
4777 iounmap(hw->regs); 4779 iounmap(hw->regs);
4778err_out_free_hw: 4780err_out_free_hw:
@@ -4810,7 +4812,8 @@ static void __devexit sky2_remove(struct pci_dev *pdev)
4810 free_irq(pdev->irq, hw); 4812 free_irq(pdev->irq, hw);
4811 if (hw->flags & SKY2_HW_USE_MSI) 4813 if (hw->flags & SKY2_HW_USE_MSI)
4812 pci_disable_msi(pdev); 4814 pci_disable_msi(pdev);
4813 pci_free_consistent(pdev, STATUS_LE_BYTES, hw->st_le, hw->st_dma); 4815 pci_free_consistent(pdev, hw->st_size * sizeof(struct sky2_status_le),
4816 hw->st_le, hw->st_dma);
4814 pci_release_regions(pdev); 4817 pci_release_regions(pdev);
4815 pci_disable_device(pdev); 4818 pci_disable_device(pdev);
4816 4819
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index 0bebfb3638f6..125b5bd01524 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -2268,6 +2268,7 @@ struct sky2_hw {
2268 u8 ports; 2268 u8 ports;
2269 2269
2270 struct sky2_status_le *st_le; 2270 struct sky2_status_le *st_le;
2271 u32 st_size;
2271 u32 st_idx; 2272 u32 st_idx;
2272 dma_addr_t st_dma; 2273 dma_addr_t st_dma;
2273 2274