diff options
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r-- | drivers/net/sky2.c | 134 |
1 files changed, 106 insertions, 28 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 3a086d3a7cbf..bf9c05be347b 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 | ||
87 | static const u32 default_msg = | 84 | static const u32 default_msg = |
@@ -1132,7 +1129,7 @@ static int sky2_rx_map_skb(struct pci_dev *pdev, struct rx_ring_info *re, | |||
1132 | if (pci_dma_mapping_error(pdev, re->data_addr)) | 1129 | if (pci_dma_mapping_error(pdev, re->data_addr)) |
1133 | goto mapping_error; | 1130 | goto mapping_error; |
1134 | 1131 | ||
1135 | pci_unmap_len_set(re, data_size, size); | 1132 | dma_unmap_len_set(re, data_size, size); |
1136 | 1133 | ||
1137 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { | 1134 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { |
1138 | skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; | 1135 | skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; |
@@ -1154,7 +1151,7 @@ map_page_error: | |||
1154 | PCI_DMA_FROMDEVICE); | 1151 | PCI_DMA_FROMDEVICE); |
1155 | } | 1152 | } |
1156 | 1153 | ||
1157 | pci_unmap_single(pdev, re->data_addr, pci_unmap_len(re, data_size), | 1154 | pci_unmap_single(pdev, re->data_addr, dma_unmap_len(re, data_size), |
1158 | PCI_DMA_FROMDEVICE); | 1155 | PCI_DMA_FROMDEVICE); |
1159 | 1156 | ||
1160 | mapping_error: | 1157 | mapping_error: |
@@ -1169,7 +1166,7 @@ static void sky2_rx_unmap_skb(struct pci_dev *pdev, struct rx_ring_info *re) | |||
1169 | struct sk_buff *skb = re->skb; | 1166 | struct sk_buff *skb = re->skb; |
1170 | int i; | 1167 | int i; |
1171 | 1168 | ||
1172 | pci_unmap_single(pdev, re->data_addr, pci_unmap_len(re, data_size), | 1169 | pci_unmap_single(pdev, re->data_addr, dma_unmap_len(re, data_size), |
1173 | PCI_DMA_FROMDEVICE); | 1170 | PCI_DMA_FROMDEVICE); |
1174 | 1171 | ||
1175 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) | 1172 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) |
@@ -1196,6 +1193,39 @@ static void rx_set_checksum(struct sky2_port *sky2) | |||
1196 | ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); | 1193 | ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); |
1197 | } | 1194 | } |
1198 | 1195 | ||
1196 | /* Enable/disable receive hash calculation (RSS) */ | ||
1197 | static void rx_set_rss(struct net_device *dev) | ||
1198 | { | ||
1199 | struct sky2_port *sky2 = netdev_priv(dev); | ||
1200 | struct sky2_hw *hw = sky2->hw; | ||
1201 | int i, nkeys = 4; | ||
1202 | |||
1203 | /* Supports IPv6 and other modes */ | ||
1204 | if (hw->flags & SKY2_HW_NEW_LE) { | ||
1205 | nkeys = 10; | ||
1206 | sky2_write32(hw, SK_REG(sky2->port, RSS_CFG), HASH_ALL); | ||
1207 | } | ||
1208 | |||
1209 | /* Program RSS initial values */ | ||
1210 | if (dev->features & NETIF_F_RXHASH) { | ||
1211 | u32 key[nkeys]; | ||
1212 | |||
1213 | get_random_bytes(key, nkeys * sizeof(u32)); | ||
1214 | for (i = 0; i < nkeys; i++) | ||
1215 | sky2_write32(hw, SK_REG(sky2->port, RSS_KEY + i * 4), | ||
1216 | key[i]); | ||
1217 | |||
1218 | /* Need to turn on (undocumented) flag to make hashing work */ | ||
1219 | sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), | ||
1220 | RX_STFW_ENA); | ||
1221 | |||
1222 | sky2_write32(hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR), | ||
1223 | BMU_ENA_RX_RSS_HASH); | ||
1224 | } else | ||
1225 | sky2_write32(hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR), | ||
1226 | BMU_DIS_RX_RSS_HASH); | ||
1227 | } | ||
1228 | |||
1199 | /* | 1229 | /* |
1200 | * The RX Stop command will not work for Yukon-2 if the BMU does not | 1230 | * The RX Stop command will not work for Yukon-2 if the BMU does not |
1201 | * reach the end of packet and since we can't make sure that we have | 1231 | * reach the end of packet and since we can't make sure that we have |
@@ -1428,6 +1458,9 @@ static void sky2_rx_start(struct sky2_port *sky2) | |||
1428 | if (!(hw->flags & SKY2_HW_NEW_LE)) | 1458 | if (!(hw->flags & SKY2_HW_NEW_LE)) |
1429 | rx_set_checksum(sky2); | 1459 | rx_set_checksum(sky2); |
1430 | 1460 | ||
1461 | if (!(hw->flags & SKY2_HW_RSS_BROKEN)) | ||
1462 | rx_set_rss(sky2->netdev); | ||
1463 | |||
1431 | /* submit Rx ring */ | 1464 | /* submit Rx ring */ |
1432 | for (i = 0; i < sky2->rx_pending; i++) { | 1465 | for (i = 0; i < sky2->rx_pending; i++) { |
1433 | re = sky2->rx_ring + i; | 1466 | re = sky2->rx_ring + i; |
@@ -1662,12 +1695,12 @@ static unsigned tx_le_req(const struct sk_buff *skb) | |||
1662 | static void sky2_tx_unmap(struct pci_dev *pdev, struct tx_ring_info *re) | 1695 | static void sky2_tx_unmap(struct pci_dev *pdev, struct tx_ring_info *re) |
1663 | { | 1696 | { |
1664 | if (re->flags & TX_MAP_SINGLE) | 1697 | if (re->flags & TX_MAP_SINGLE) |
1665 | pci_unmap_single(pdev, pci_unmap_addr(re, mapaddr), | 1698 | pci_unmap_single(pdev, dma_unmap_addr(re, mapaddr), |
1666 | pci_unmap_len(re, maplen), | 1699 | dma_unmap_len(re, maplen), |
1667 | PCI_DMA_TODEVICE); | 1700 | PCI_DMA_TODEVICE); |
1668 | else if (re->flags & TX_MAP_PAGE) | 1701 | else if (re->flags & TX_MAP_PAGE) |
1669 | pci_unmap_page(pdev, pci_unmap_addr(re, mapaddr), | 1702 | pci_unmap_page(pdev, dma_unmap_addr(re, mapaddr), |
1670 | pci_unmap_len(re, maplen), | 1703 | dma_unmap_len(re, maplen), |
1671 | PCI_DMA_TODEVICE); | 1704 | PCI_DMA_TODEVICE); |
1672 | re->flags = 0; | 1705 | re->flags = 0; |
1673 | } | 1706 | } |
@@ -1778,8 +1811,8 @@ static netdev_tx_t sky2_xmit_frame(struct sk_buff *skb, | |||
1778 | 1811 | ||
1779 | re = sky2->tx_ring + slot; | 1812 | re = sky2->tx_ring + slot; |
1780 | re->flags = TX_MAP_SINGLE; | 1813 | re->flags = TX_MAP_SINGLE; |
1781 | pci_unmap_addr_set(re, mapaddr, mapping); | 1814 | dma_unmap_addr_set(re, mapaddr, mapping); |
1782 | pci_unmap_len_set(re, maplen, len); | 1815 | dma_unmap_len_set(re, maplen, len); |
1783 | 1816 | ||
1784 | le = get_tx_le(sky2, &slot); | 1817 | le = get_tx_le(sky2, &slot); |
1785 | le->addr = cpu_to_le32(lower_32_bits(mapping)); | 1818 | le->addr = cpu_to_le32(lower_32_bits(mapping)); |
@@ -1807,8 +1840,8 @@ static netdev_tx_t sky2_xmit_frame(struct sk_buff *skb, | |||
1807 | 1840 | ||
1808 | re = sky2->tx_ring + slot; | 1841 | re = sky2->tx_ring + slot; |
1809 | re->flags = TX_MAP_PAGE; | 1842 | re->flags = TX_MAP_PAGE; |
1810 | pci_unmap_addr_set(re, mapaddr, mapping); | 1843 | dma_unmap_addr_set(re, mapaddr, mapping); |
1811 | pci_unmap_len_set(re, maplen, frag->size); | 1844 | dma_unmap_len_set(re, maplen, frag->size); |
1812 | 1845 | ||
1813 | le = get_tx_le(sky2, &slot); | 1846 | le = get_tx_le(sky2, &slot); |
1814 | le->addr = cpu_to_le32(lower_32_bits(mapping)); | 1847 | le->addr = cpu_to_le32(lower_32_bits(mapping)); |
@@ -2537,6 +2570,14 @@ static void sky2_rx_checksum(struct sky2_port *sky2, u32 status) | |||
2537 | } | 2570 | } |
2538 | } | 2571 | } |
2539 | 2572 | ||
2573 | static void sky2_rx_hash(struct sky2_port *sky2, u32 status) | ||
2574 | { | ||
2575 | struct sk_buff *skb; | ||
2576 | |||
2577 | skb = sky2->rx_ring[sky2->rx_next].skb; | ||
2578 | skb->rxhash = le32_to_cpu(status); | ||
2579 | } | ||
2580 | |||
2540 | /* Process status response ring */ | 2581 | /* Process status response ring */ |
2541 | static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) | 2582 | static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) |
2542 | { | 2583 | { |
@@ -2558,7 +2599,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) | |||
2558 | if (!(opcode & HW_OWNER)) | 2599 | if (!(opcode & HW_OWNER)) |
2559 | break; | 2600 | break; |
2560 | 2601 | ||
2561 | hw->st_idx = RING_NEXT(hw->st_idx, STATUS_RING_SIZE); | 2602 | hw->st_idx = RING_NEXT(hw->st_idx, hw->st_size); |
2562 | 2603 | ||
2563 | port = le->css & CSS_LINK_BIT; | 2604 | port = le->css & CSS_LINK_BIT; |
2564 | dev = hw->dev[port]; | 2605 | dev = hw->dev[port]; |
@@ -2609,6 +2650,10 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) | |||
2609 | sky2_rx_checksum(sky2, status); | 2650 | sky2_rx_checksum(sky2, status); |
2610 | break; | 2651 | break; |
2611 | 2652 | ||
2653 | case OP_RSS_HASH: | ||
2654 | sky2_rx_hash(sky2, status); | ||
2655 | break; | ||
2656 | |||
2612 | case OP_TXINDEXLE: | 2657 | case OP_TXINDEXLE: |
2613 | /* TX index reports status for both ports */ | 2658 | /* TX index reports status for both ports */ |
2614 | sky2_tx_done(hw->dev[0], status & 0xfff); | 2659 | sky2_tx_done(hw->dev[0], status & 0xfff); |
@@ -2963,6 +3008,8 @@ static int __devinit sky2_init(struct sky2_hw *hw) | |||
2963 | switch(hw->chip_id) { | 3008 | switch(hw->chip_id) { |
2964 | case CHIP_ID_YUKON_XL: | 3009 | case CHIP_ID_YUKON_XL: |
2965 | hw->flags = SKY2_HW_GIGABIT | SKY2_HW_NEWER_PHY; | 3010 | hw->flags = SKY2_HW_GIGABIT | SKY2_HW_NEWER_PHY; |
3011 | if (hw->chip_rev < CHIP_REV_YU_XL_A2) | ||
3012 | hw->flags |= SKY2_HW_RSS_BROKEN; | ||
2966 | break; | 3013 | break; |
2967 | 3014 | ||
2968 | case CHIP_ID_YUKON_EC_U: | 3015 | case CHIP_ID_YUKON_EC_U: |
@@ -2988,10 +3035,11 @@ static int __devinit sky2_init(struct sky2_hw *hw) | |||
2988 | dev_err(&hw->pdev->dev, "unsupported revision Yukon-EC rev A1\n"); | 3035 | dev_err(&hw->pdev->dev, "unsupported revision Yukon-EC rev A1\n"); |
2989 | return -EOPNOTSUPP; | 3036 | return -EOPNOTSUPP; |
2990 | } | 3037 | } |
2991 | hw->flags = SKY2_HW_GIGABIT; | 3038 | hw->flags = SKY2_HW_GIGABIT | SKY2_HW_RSS_BROKEN; |
2992 | break; | 3039 | break; |
2993 | 3040 | ||
2994 | case CHIP_ID_YUKON_FE: | 3041 | case CHIP_ID_YUKON_FE: |
3042 | hw->flags = SKY2_HW_RSS_BROKEN; | ||
2995 | break; | 3043 | break; |
2996 | 3044 | ||
2997 | case CHIP_ID_YUKON_FE_P: | 3045 | case CHIP_ID_YUKON_FE_P: |
@@ -3198,7 +3246,7 @@ static void sky2_reset(struct sky2_hw *hw) | |||
3198 | for (i = 0; i < hw->ports; i++) | 3246 | for (i = 0; i < hw->ports; i++) |
3199 | sky2_gmac_reset(hw, i); | 3247 | sky2_gmac_reset(hw, i); |
3200 | 3248 | ||
3201 | memset(hw->st_le, 0, STATUS_LE_BYTES); | 3249 | memset(hw->st_le, 0, hw->st_size * sizeof(struct sky2_status_le)); |
3202 | hw->st_idx = 0; | 3250 | hw->st_idx = 0; |
3203 | 3251 | ||
3204 | sky2_write32(hw, STAT_CTRL, SC_STAT_RST_SET); | 3252 | sky2_write32(hw, STAT_CTRL, SC_STAT_RST_SET); |
@@ -3208,7 +3256,7 @@ static void sky2_reset(struct sky2_hw *hw) | |||
3208 | sky2_write32(hw, STAT_LIST_ADDR_HI, (u64) hw->st_dma >> 32); | 3256 | sky2_write32(hw, STAT_LIST_ADDR_HI, (u64) hw->st_dma >> 32); |
3209 | 3257 | ||
3210 | /* Set the list last index */ | 3258 | /* Set the list last index */ |
3211 | sky2_write16(hw, STAT_LAST_IDX, STATUS_RING_SIZE - 1); | 3259 | sky2_write16(hw, STAT_LAST_IDX, hw->st_size - 1); |
3212 | 3260 | ||
3213 | sky2_write16(hw, STAT_TX_IDX_TH, 10); | 3261 | sky2_write16(hw, STAT_TX_IDX_TH, 10); |
3214 | sky2_write8(hw, STAT_FIFO_WM, 16); | 3262 | sky2_write8(hw, STAT_FIFO_WM, 16); |
@@ -4115,6 +4163,25 @@ static int sky2_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom | |||
4115 | return sky2_vpd_write(sky2->hw, cap, data, eeprom->offset, eeprom->len); | 4163 | return sky2_vpd_write(sky2->hw, cap, data, eeprom->offset, eeprom->len); |
4116 | } | 4164 | } |
4117 | 4165 | ||
4166 | static int sky2_set_flags(struct net_device *dev, u32 data) | ||
4167 | { | ||
4168 | struct sky2_port *sky2 = netdev_priv(dev); | ||
4169 | |||
4170 | if (data & ~ETH_FLAG_RXHASH) | ||
4171 | return -EOPNOTSUPP; | ||
4172 | |||
4173 | if (data & ETH_FLAG_RXHASH) { | ||
4174 | if (sky2->hw->flags & SKY2_HW_RSS_BROKEN) | ||
4175 | return -EINVAL; | ||
4176 | |||
4177 | dev->features |= NETIF_F_RXHASH; | ||
4178 | } else | ||
4179 | dev->features &= ~NETIF_F_RXHASH; | ||
4180 | |||
4181 | rx_set_rss(dev); | ||
4182 | |||
4183 | return 0; | ||
4184 | } | ||
4118 | 4185 | ||
4119 | static const struct ethtool_ops sky2_ethtool_ops = { | 4186 | static const struct ethtool_ops sky2_ethtool_ops = { |
4120 | .get_settings = sky2_get_settings, | 4187 | .get_settings = sky2_get_settings, |
@@ -4146,6 +4213,7 @@ static const struct ethtool_ops sky2_ethtool_ops = { | |||
4146 | .phys_id = sky2_phys_id, | 4213 | .phys_id = sky2_phys_id, |
4147 | .get_sset_count = sky2_get_sset_count, | 4214 | .get_sset_count = sky2_get_sset_count, |
4148 | .get_ethtool_stats = sky2_get_ethtool_stats, | 4215 | .get_ethtool_stats = sky2_get_ethtool_stats, |
4216 | .set_flags = sky2_set_flags, | ||
4149 | }; | 4217 | }; |
4150 | 4218 | ||
4151 | #ifdef CONFIG_SKY2_DEBUG | 4219 | #ifdef CONFIG_SKY2_DEBUG |
@@ -4256,12 +4324,13 @@ static int sky2_debug_show(struct seq_file *seq, void *v) | |||
4256 | napi_disable(&hw->napi); | 4324 | napi_disable(&hw->napi); |
4257 | last = sky2_read16(hw, STAT_PUT_IDX); | 4325 | last = sky2_read16(hw, STAT_PUT_IDX); |
4258 | 4326 | ||
4327 | seq_printf(seq, "Status ring %u\n", hw->st_size); | ||
4259 | if (hw->st_idx == last) | 4328 | if (hw->st_idx == last) |
4260 | seq_puts(seq, "Status ring (empty)\n"); | 4329 | seq_puts(seq, "Status ring (empty)\n"); |
4261 | else { | 4330 | else { |
4262 | seq_puts(seq, "Status ring\n"); | 4331 | seq_puts(seq, "Status ring\n"); |
4263 | for (idx = hw->st_idx; idx != last && idx < STATUS_RING_SIZE; | 4332 | for (idx = hw->st_idx; idx != last && idx < hw->st_size; |
4264 | idx = RING_NEXT(idx, STATUS_RING_SIZE)) { | 4333 | idx = RING_NEXT(idx, hw->st_size)) { |
4265 | const struct sky2_status_le *le = hw->st_le + idx; | 4334 | const struct sky2_status_le *le = hw->st_le + idx; |
4266 | seq_printf(seq, "[%d] %#x %d %#x\n", | 4335 | seq_printf(seq, "[%d] %#x %d %#x\n", |
4267 | idx, le->opcode, le->length, le->status); | 4336 | idx, le->opcode, le->length, le->status); |
@@ -4498,6 +4567,10 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, | |||
4498 | if (highmem) | 4567 | if (highmem) |
4499 | dev->features |= NETIF_F_HIGHDMA; | 4568 | dev->features |= NETIF_F_HIGHDMA; |
4500 | 4569 | ||
4570 | /* Enable receive hashing unless hardware is known broken */ | ||
4571 | if (!(hw->flags & SKY2_HW_RSS_BROKEN)) | ||
4572 | dev->features |= NETIF_F_RXHASH; | ||
4573 | |||
4501 | #ifdef SKY2_VLAN_TAG_USED | 4574 | #ifdef SKY2_VLAN_TAG_USED |
4502 | /* The workaround for FE+ status conflicts with VLAN tag detection. */ | 4575 | /* The workaround for FE+ status conflicts with VLAN tag detection. */ |
4503 | if (!(sky2->hw->chip_id == CHIP_ID_YUKON_FE_P && | 4576 | if (!(sky2->hw->chip_id == CHIP_ID_YUKON_FE_P && |
@@ -4689,15 +4762,17 @@ static int __devinit sky2_probe(struct pci_dev *pdev, | |||
4689 | goto err_out_free_hw; | 4762 | goto err_out_free_hw; |
4690 | } | 4763 | } |
4691 | 4764 | ||
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); | 4765 | err = sky2_init(hw); |
4698 | if (err) | 4766 | if (err) |
4699 | goto err_out_iounmap; | 4767 | goto err_out_iounmap; |
4700 | 4768 | ||
4769 | /* ring for status responses */ | ||
4770 | hw->st_size = hw->ports * roundup_pow_of_two(3*RX_MAX_PENDING + TX_MAX_PENDING); | ||
4771 | hw->st_le = pci_alloc_consistent(pdev, hw->st_size * sizeof(struct sky2_status_le), | ||
4772 | &hw->st_dma); | ||
4773 | if (!hw->st_le) | ||
4774 | goto err_out_reset; | ||
4775 | |||
4701 | dev_info(&pdev->dev, "Yukon-2 %s chip revision %d\n", | 4776 | dev_info(&pdev->dev, "Yukon-2 %s chip revision %d\n", |
4702 | sky2_name(hw->chip_id, buf1, sizeof(buf1)), hw->chip_rev); | 4777 | sky2_name(hw->chip_id, buf1, sizeof(buf1)), hw->chip_rev); |
4703 | 4778 | ||
@@ -4771,8 +4846,10 @@ err_out_unregister: | |||
4771 | err_out_free_netdev: | 4846 | err_out_free_netdev: |
4772 | free_netdev(dev); | 4847 | free_netdev(dev); |
4773 | err_out_free_pci: | 4848 | err_out_free_pci: |
4849 | pci_free_consistent(pdev, hw->st_size * sizeof(struct sky2_status_le), | ||
4850 | hw->st_le, hw->st_dma); | ||
4851 | err_out_reset: | ||
4774 | sky2_write8(hw, B0_CTST, CS_RST_SET); | 4852 | sky2_write8(hw, B0_CTST, CS_RST_SET); |
4775 | pci_free_consistent(pdev, STATUS_LE_BYTES, hw->st_le, hw->st_dma); | ||
4776 | err_out_iounmap: | 4853 | err_out_iounmap: |
4777 | iounmap(hw->regs); | 4854 | iounmap(hw->regs); |
4778 | err_out_free_hw: | 4855 | err_out_free_hw: |
@@ -4810,7 +4887,8 @@ static void __devexit sky2_remove(struct pci_dev *pdev) | |||
4810 | free_irq(pdev->irq, hw); | 4887 | free_irq(pdev->irq, hw); |
4811 | if (hw->flags & SKY2_HW_USE_MSI) | 4888 | if (hw->flags & SKY2_HW_USE_MSI) |
4812 | pci_disable_msi(pdev); | 4889 | pci_disable_msi(pdev); |
4813 | pci_free_consistent(pdev, STATUS_LE_BYTES, hw->st_le, hw->st_dma); | 4890 | pci_free_consistent(pdev, hw->st_size * sizeof(struct sky2_status_le), |
4891 | hw->st_le, hw->st_dma); | ||
4814 | pci_release_regions(pdev); | 4892 | pci_release_regions(pdev); |
4815 | pci_disable_device(pdev); | 4893 | pci_disable_device(pdev); |
4816 | 4894 | ||