diff options
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r-- | drivers/net/sky2.c | 267 |
1 files changed, 172 insertions, 95 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 994703cc0db3..d01c56eb9627 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -1068,13 +1068,16 @@ static void sky2_rx_submit(struct sky2_port *sky2, | |||
1068 | } | 1068 | } |
1069 | 1069 | ||
1070 | 1070 | ||
1071 | static void sky2_rx_map_skb(struct pci_dev *pdev, struct rx_ring_info *re, | 1071 | static int sky2_rx_map_skb(struct pci_dev *pdev, struct rx_ring_info *re, |
1072 | unsigned size) | 1072 | unsigned size) |
1073 | { | 1073 | { |
1074 | struct sk_buff *skb = re->skb; | 1074 | struct sk_buff *skb = re->skb; |
1075 | int i; | 1075 | int i; |
1076 | 1076 | ||
1077 | re->data_addr = pci_map_single(pdev, skb->data, size, PCI_DMA_FROMDEVICE); | 1077 | re->data_addr = pci_map_single(pdev, skb->data, size, PCI_DMA_FROMDEVICE); |
1078 | if (unlikely(pci_dma_mapping_error(pdev, re->data_addr))) | ||
1079 | return -EIO; | ||
1080 | |||
1078 | pci_unmap_len_set(re, data_size, size); | 1081 | pci_unmap_len_set(re, data_size, size); |
1079 | 1082 | ||
1080 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) | 1083 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) |
@@ -1083,6 +1086,7 @@ static void sky2_rx_map_skb(struct pci_dev *pdev, struct rx_ring_info *re, | |||
1083 | skb_shinfo(skb)->frags[i].page_offset, | 1086 | skb_shinfo(skb)->frags[i].page_offset, |
1084 | skb_shinfo(skb)->frags[i].size, | 1087 | skb_shinfo(skb)->frags[i].size, |
1085 | PCI_DMA_FROMDEVICE); | 1088 | PCI_DMA_FROMDEVICE); |
1089 | return 0; | ||
1086 | } | 1090 | } |
1087 | 1091 | ||
1088 | static void sky2_rx_unmap_skb(struct pci_dev *pdev, struct rx_ring_info *re) | 1092 | static void sky2_rx_unmap_skb(struct pci_dev *pdev, struct rx_ring_info *re) |
@@ -1354,7 +1358,12 @@ static int sky2_rx_start(struct sky2_port *sky2) | |||
1354 | if (!re->skb) | 1358 | if (!re->skb) |
1355 | goto nomem; | 1359 | goto nomem; |
1356 | 1360 | ||
1357 | sky2_rx_map_skb(hw->pdev, re, sky2->rx_data_size); | 1361 | if (sky2_rx_map_skb(hw->pdev, re, sky2->rx_data_size)) { |
1362 | dev_kfree_skb(re->skb); | ||
1363 | re->skb = NULL; | ||
1364 | goto nomem; | ||
1365 | } | ||
1366 | |||
1358 | sky2_rx_submit(sky2, re); | 1367 | sky2_rx_submit(sky2, re); |
1359 | } | 1368 | } |
1360 | 1369 | ||
@@ -1547,7 +1556,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
1547 | struct sky2_hw *hw = sky2->hw; | 1556 | struct sky2_hw *hw = sky2->hw; |
1548 | struct sky2_tx_le *le = NULL; | 1557 | struct sky2_tx_le *le = NULL; |
1549 | struct tx_ring_info *re; | 1558 | struct tx_ring_info *re; |
1550 | unsigned i, len; | 1559 | unsigned i, len, first_slot; |
1551 | dma_addr_t mapping; | 1560 | dma_addr_t mapping; |
1552 | u16 mss; | 1561 | u16 mss; |
1553 | u8 ctrl; | 1562 | u8 ctrl; |
@@ -1555,13 +1564,17 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
1555 | if (unlikely(tx_avail(sky2) < tx_le_req(skb))) | 1564 | if (unlikely(tx_avail(sky2) < tx_le_req(skb))) |
1556 | return NETDEV_TX_BUSY; | 1565 | return NETDEV_TX_BUSY; |
1557 | 1566 | ||
1558 | if (unlikely(netif_msg_tx_queued(sky2))) | ||
1559 | printk(KERN_DEBUG "%s: tx queued, slot %u, len %d\n", | ||
1560 | dev->name, sky2->tx_prod, skb->len); | ||
1561 | |||
1562 | len = skb_headlen(skb); | 1567 | len = skb_headlen(skb); |
1563 | mapping = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE); | 1568 | mapping = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE); |
1564 | 1569 | ||
1570 | if (pci_dma_mapping_error(hw->pdev, mapping)) | ||
1571 | goto mapping_error; | ||
1572 | |||
1573 | first_slot = sky2->tx_prod; | ||
1574 | if (unlikely(netif_msg_tx_queued(sky2))) | ||
1575 | printk(KERN_DEBUG "%s: tx queued, slot %u, len %d\n", | ||
1576 | dev->name, first_slot, skb->len); | ||
1577 | |||
1565 | /* Send high bits if needed */ | 1578 | /* Send high bits if needed */ |
1566 | if (sizeof(dma_addr_t) > sizeof(u32)) { | 1579 | if (sizeof(dma_addr_t) > sizeof(u32)) { |
1567 | le = get_tx_le(sky2); | 1580 | le = get_tx_le(sky2); |
@@ -1648,6 +1661,9 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
1648 | mapping = pci_map_page(hw->pdev, frag->page, frag->page_offset, | 1661 | mapping = pci_map_page(hw->pdev, frag->page, frag->page_offset, |
1649 | frag->size, PCI_DMA_TODEVICE); | 1662 | frag->size, PCI_DMA_TODEVICE); |
1650 | 1663 | ||
1664 | if (pci_dma_mapping_error(hw->pdev, mapping)) | ||
1665 | goto mapping_unwind; | ||
1666 | |||
1651 | if (sizeof(dma_addr_t) > sizeof(u32)) { | 1667 | if (sizeof(dma_addr_t) > sizeof(u32)) { |
1652 | le = get_tx_le(sky2); | 1668 | le = get_tx_le(sky2); |
1653 | le->addr = cpu_to_le32(upper_32_bits(mapping)); | 1669 | le->addr = cpu_to_le32(upper_32_bits(mapping)); |
@@ -1676,6 +1692,34 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
1676 | 1692 | ||
1677 | dev->trans_start = jiffies; | 1693 | dev->trans_start = jiffies; |
1678 | return NETDEV_TX_OK; | 1694 | return NETDEV_TX_OK; |
1695 | |||
1696 | mapping_unwind: | ||
1697 | for (i = first_slot; i != sky2->tx_prod; i = RING_NEXT(i, TX_RING_SIZE)) { | ||
1698 | le = sky2->tx_le + i; | ||
1699 | re = sky2->tx_ring + i; | ||
1700 | |||
1701 | switch(le->opcode & ~HW_OWNER) { | ||
1702 | case OP_LARGESEND: | ||
1703 | case OP_PACKET: | ||
1704 | pci_unmap_single(hw->pdev, | ||
1705 | pci_unmap_addr(re, mapaddr), | ||
1706 | pci_unmap_len(re, maplen), | ||
1707 | PCI_DMA_TODEVICE); | ||
1708 | break; | ||
1709 | case OP_BUFFER: | ||
1710 | pci_unmap_page(hw->pdev, pci_unmap_addr(re, mapaddr), | ||
1711 | pci_unmap_len(re, maplen), | ||
1712 | PCI_DMA_TODEVICE); | ||
1713 | break; | ||
1714 | } | ||
1715 | } | ||
1716 | |||
1717 | sky2->tx_prod = first_slot; | ||
1718 | mapping_error: | ||
1719 | if (net_ratelimit()) | ||
1720 | dev_warn(&hw->pdev->dev, "%s: tx mapping error\n", dev->name); | ||
1721 | dev_kfree_skb(skb); | ||
1722 | return NETDEV_TX_OK; | ||
1679 | } | 1723 | } |
1680 | 1724 | ||
1681 | /* | 1725 | /* |
@@ -2191,7 +2235,11 @@ static struct sk_buff *receive_new(struct sky2_port *sky2, | |||
2191 | 2235 | ||
2192 | prefetch(skb->data); | 2236 | prefetch(skb->data); |
2193 | re->skb = nskb; | 2237 | re->skb = nskb; |
2194 | sky2_rx_map_skb(sky2->hw->pdev, re, hdr_space); | 2238 | if (sky2_rx_map_skb(sky2->hw->pdev, re, hdr_space)) { |
2239 | dev_kfree_skb(nskb); | ||
2240 | re->skb = skb; | ||
2241 | return NULL; | ||
2242 | } | ||
2195 | 2243 | ||
2196 | if (skb_shinfo(skb)->nr_frags) | 2244 | if (skb_shinfo(skb)->nr_frags) |
2197 | skb_put_frags(skb, hdr_space, length); | 2245 | skb_put_frags(skb, hdr_space, length); |
@@ -2687,13 +2735,6 @@ static int sky2_poll(struct napi_struct *napi, int work_limit) | |||
2687 | goto done; | 2735 | goto done; |
2688 | } | 2736 | } |
2689 | 2737 | ||
2690 | /* Bug/Errata workaround? | ||
2691 | * Need to kick the TX irq moderation timer. | ||
2692 | */ | ||
2693 | if (sky2_read8(hw, STAT_TX_TIMER_CTRL) == TIM_START) { | ||
2694 | sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP); | ||
2695 | sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START); | ||
2696 | } | ||
2697 | napi_complete(napi); | 2738 | napi_complete(napi); |
2698 | sky2_read32(hw, B0_Y2_SP_LISR); | 2739 | sky2_read32(hw, B0_Y2_SP_LISR); |
2699 | done: | 2740 | done: |
@@ -3864,6 +3905,86 @@ static const struct ethtool_ops sky2_ethtool_ops = { | |||
3864 | 3905 | ||
3865 | static struct dentry *sky2_debug; | 3906 | static struct dentry *sky2_debug; |
3866 | 3907 | ||
3908 | |||
3909 | /* | ||
3910 | * Read and parse the first part of Vital Product Data | ||
3911 | */ | ||
3912 | #define VPD_SIZE 128 | ||
3913 | #define VPD_MAGIC 0x82 | ||
3914 | |||
3915 | static const struct vpd_tag { | ||
3916 | char tag[2]; | ||
3917 | char *label; | ||
3918 | } vpd_tags[] = { | ||
3919 | { "PN", "Part Number" }, | ||
3920 | { "EC", "Engineering Level" }, | ||
3921 | { "MN", "Manufacturer" }, | ||
3922 | { "SN", "Serial Number" }, | ||
3923 | { "YA", "Asset Tag" }, | ||
3924 | { "VL", "First Error Log Message" }, | ||
3925 | { "VF", "Second Error Log Message" }, | ||
3926 | { "VB", "Boot Agent ROM Configuration" }, | ||
3927 | { "VE", "EFI UNDI Configuration" }, | ||
3928 | }; | ||
3929 | |||
3930 | static void sky2_show_vpd(struct seq_file *seq, struct sky2_hw *hw) | ||
3931 | { | ||
3932 | size_t vpd_size; | ||
3933 | loff_t offs; | ||
3934 | u8 len; | ||
3935 | unsigned char *buf; | ||
3936 | u16 reg2; | ||
3937 | |||
3938 | reg2 = sky2_pci_read16(hw, PCI_DEV_REG2); | ||
3939 | vpd_size = 1 << ( ((reg2 & PCI_VPD_ROM_SZ) >> 14) + 8); | ||
3940 | |||
3941 | seq_printf(seq, "%s Product Data\n", pci_name(hw->pdev)); | ||
3942 | buf = kmalloc(vpd_size, GFP_KERNEL); | ||
3943 | if (!buf) { | ||
3944 | seq_puts(seq, "no memory!\n"); | ||
3945 | return; | ||
3946 | } | ||
3947 | |||
3948 | if (pci_read_vpd(hw->pdev, 0, vpd_size, buf) < 0) { | ||
3949 | seq_puts(seq, "VPD read failed\n"); | ||
3950 | goto out; | ||
3951 | } | ||
3952 | |||
3953 | if (buf[0] != VPD_MAGIC) { | ||
3954 | seq_printf(seq, "VPD tag mismatch: %#x\n", buf[0]); | ||
3955 | goto out; | ||
3956 | } | ||
3957 | len = buf[1]; | ||
3958 | if (len == 0 || len > vpd_size - 4) { | ||
3959 | seq_printf(seq, "Invalid id length: %d\n", len); | ||
3960 | goto out; | ||
3961 | } | ||
3962 | |||
3963 | seq_printf(seq, "%.*s\n", len, buf + 3); | ||
3964 | offs = len + 3; | ||
3965 | |||
3966 | while (offs < vpd_size - 4) { | ||
3967 | int i; | ||
3968 | |||
3969 | if (!memcmp("RW", buf + offs, 2)) /* end marker */ | ||
3970 | break; | ||
3971 | len = buf[offs + 2]; | ||
3972 | if (offs + len + 3 >= vpd_size) | ||
3973 | break; | ||
3974 | |||
3975 | for (i = 0; i < ARRAY_SIZE(vpd_tags); i++) { | ||
3976 | if (!memcmp(vpd_tags[i].tag, buf + offs, 2)) { | ||
3977 | seq_printf(seq, " %s: %.*s\n", | ||
3978 | vpd_tags[i].label, len, buf + offs + 3); | ||
3979 | break; | ||
3980 | } | ||
3981 | } | ||
3982 | offs += len + 3; | ||
3983 | } | ||
3984 | out: | ||
3985 | kfree(buf); | ||
3986 | } | ||
3987 | |||
3867 | static int sky2_debug_show(struct seq_file *seq, void *v) | 3988 | static int sky2_debug_show(struct seq_file *seq, void *v) |
3868 | { | 3989 | { |
3869 | struct net_device *dev = seq->private; | 3990 | struct net_device *dev = seq->private; |
@@ -3873,14 +3994,18 @@ static int sky2_debug_show(struct seq_file *seq, void *v) | |||
3873 | unsigned idx, last; | 3994 | unsigned idx, last; |
3874 | int sop; | 3995 | int sop; |
3875 | 3996 | ||
3876 | if (!netif_running(dev)) | 3997 | sky2_show_vpd(seq, hw); |
3877 | return -ENETDOWN; | ||
3878 | 3998 | ||
3879 | seq_printf(seq, "IRQ src=%x mask=%x control=%x\n", | 3999 | seq_printf(seq, "\nIRQ src=%x mask=%x control=%x\n", |
3880 | sky2_read32(hw, B0_ISRC), | 4000 | sky2_read32(hw, B0_ISRC), |
3881 | sky2_read32(hw, B0_IMSK), | 4001 | sky2_read32(hw, B0_IMSK), |
3882 | sky2_read32(hw, B0_Y2_SP_ICR)); | 4002 | sky2_read32(hw, B0_Y2_SP_ICR)); |
3883 | 4003 | ||
4004 | if (!netif_running(dev)) { | ||
4005 | seq_printf(seq, "network not running\n"); | ||
4006 | return 0; | ||
4007 | } | ||
4008 | |||
3884 | napi_disable(&hw->napi); | 4009 | napi_disable(&hw->napi); |
3885 | last = sky2_read16(hw, STAT_PUT_IDX); | 4010 | last = sky2_read16(hw, STAT_PUT_IDX); |
3886 | 4011 | ||
@@ -4204,69 +4329,6 @@ static int __devinit sky2_test_msi(struct sky2_hw *hw) | |||
4204 | return err; | 4329 | return err; |
4205 | } | 4330 | } |
4206 | 4331 | ||
4207 | /* | ||
4208 | * Read and parse the first part of Vital Product Data | ||
4209 | */ | ||
4210 | #define VPD_SIZE 128 | ||
4211 | #define VPD_MAGIC 0x82 | ||
4212 | |||
4213 | static void __devinit sky2_vpd_info(struct sky2_hw *hw) | ||
4214 | { | ||
4215 | int cap = pci_find_capability(hw->pdev, PCI_CAP_ID_VPD); | ||
4216 | const u8 *p; | ||
4217 | u8 *vpd_buf = NULL; | ||
4218 | u16 len; | ||
4219 | static struct vpd_tag { | ||
4220 | char tag[2]; | ||
4221 | char *label; | ||
4222 | } vpd_tags[] = { | ||
4223 | { "PN", "Part Number" }, | ||
4224 | { "EC", "Engineering Level" }, | ||
4225 | { "MN", "Manufacturer" }, | ||
4226 | }; | ||
4227 | |||
4228 | if (!cap) | ||
4229 | goto out; | ||
4230 | |||
4231 | vpd_buf = kmalloc(VPD_SIZE, GFP_KERNEL); | ||
4232 | if (!vpd_buf) | ||
4233 | goto out; | ||
4234 | |||
4235 | if (sky2_vpd_read(hw, cap, vpd_buf, 0, VPD_SIZE)) | ||
4236 | goto out; | ||
4237 | |||
4238 | if (vpd_buf[0] != VPD_MAGIC) | ||
4239 | goto out; | ||
4240 | len = vpd_buf[1]; | ||
4241 | if (len == 0 || len > VPD_SIZE - 4) | ||
4242 | goto out; | ||
4243 | p = vpd_buf + 3; | ||
4244 | dev_info(&hw->pdev->dev, "%.*s\n", len, p); | ||
4245 | p += len; | ||
4246 | |||
4247 | while (p < vpd_buf + VPD_SIZE - 4) { | ||
4248 | int i; | ||
4249 | |||
4250 | if (!memcmp("RW", p, 2)) /* end marker */ | ||
4251 | break; | ||
4252 | |||
4253 | len = p[2]; | ||
4254 | if (len > (p - vpd_buf) - 4) | ||
4255 | break; | ||
4256 | |||
4257 | for (i = 0; i < ARRAY_SIZE(vpd_tags); i++) { | ||
4258 | if (!memcmp(vpd_tags[i].tag, p, 2)) { | ||
4259 | printk(KERN_DEBUG " %s: %.*s\n", | ||
4260 | vpd_tags[i].label, len, p + 3); | ||
4261 | break; | ||
4262 | } | ||
4263 | } | ||
4264 | p += len + 3; | ||
4265 | } | ||
4266 | out: | ||
4267 | kfree(vpd_buf); | ||
4268 | } | ||
4269 | |||
4270 | /* This driver supports yukon2 chipset only */ | 4332 | /* This driver supports yukon2 chipset only */ |
4271 | static const char *sky2_name(u8 chipid, char *buf, int sz) | 4333 | static const char *sky2_name(u8 chipid, char *buf, int sz) |
4272 | { | 4334 | { |
@@ -4294,6 +4356,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev, | |||
4294 | struct net_device *dev; | 4356 | struct net_device *dev; |
4295 | struct sky2_hw *hw; | 4357 | struct sky2_hw *hw; |
4296 | int err, using_dac = 0, wol_default; | 4358 | int err, using_dac = 0, wol_default; |
4359 | u32 reg; | ||
4297 | char buf1[16]; | 4360 | char buf1[16]; |
4298 | 4361 | ||
4299 | err = pci_enable_device(pdev); | 4362 | err = pci_enable_device(pdev); |
@@ -4327,6 +4390,34 @@ static int __devinit sky2_probe(struct pci_dev *pdev, | |||
4327 | } | 4390 | } |
4328 | } | 4391 | } |
4329 | 4392 | ||
4393 | /* Get configuration information | ||
4394 | * Note: only regular PCI config access once to test for HW issues | ||
4395 | * other PCI access through shared memory for speed and to | ||
4396 | * avoid MMCONFIG problems. | ||
4397 | */ | ||
4398 | err = pci_read_config_dword(pdev, PCI_DEV_REG2, ®); | ||
4399 | if (err) { | ||
4400 | dev_err(&pdev->dev, "PCI read config failed\n"); | ||
4401 | goto err_out_free_regions; | ||
4402 | } | ||
4403 | |||
4404 | /* size of available VPD, only impact sysfs */ | ||
4405 | err = pci_vpd_truncate(pdev, 1ul << (((reg & PCI_VPD_ROM_SZ) >> 14) + 8)); | ||
4406 | if (err) | ||
4407 | dev_warn(&pdev->dev, "Can't set VPD size\n"); | ||
4408 | |||
4409 | #ifdef __BIG_ENDIAN | ||
4410 | /* The sk98lin vendor driver uses hardware byte swapping but | ||
4411 | * this driver uses software swapping. | ||
4412 | */ | ||
4413 | reg &= ~PCI_REV_DESC; | ||
4414 | err = pci_write_config_dword(pdev,PCI_DEV_REG2, reg); | ||
4415 | if (err) { | ||
4416 | dev_err(&pdev->dev, "PCI write config failed\n"); | ||
4417 | goto err_out_free_regions; | ||
4418 | } | ||
4419 | #endif | ||
4420 | |||
4330 | wol_default = device_may_wakeup(&pdev->dev) ? WAKE_MAGIC : 0; | 4421 | wol_default = device_may_wakeup(&pdev->dev) ? WAKE_MAGIC : 0; |
4331 | 4422 | ||
4332 | err = -ENOMEM; | 4423 | err = -ENOMEM; |
@@ -4344,18 +4435,6 @@ static int __devinit sky2_probe(struct pci_dev *pdev, | |||
4344 | goto err_out_free_hw; | 4435 | goto err_out_free_hw; |
4345 | } | 4436 | } |
4346 | 4437 | ||
4347 | #ifdef __BIG_ENDIAN | ||
4348 | /* The sk98lin vendor driver uses hardware byte swapping but | ||
4349 | * this driver uses software swapping. | ||
4350 | */ | ||
4351 | { | ||
4352 | u32 reg; | ||
4353 | reg = sky2_pci_read32(hw, PCI_DEV_REG2); | ||
4354 | reg &= ~PCI_REV_DESC; | ||
4355 | sky2_pci_write32(hw, PCI_DEV_REG2, reg); | ||
4356 | } | ||
4357 | #endif | ||
4358 | |||
4359 | /* ring for status responses */ | 4438 | /* ring for status responses */ |
4360 | hw->st_le = pci_alloc_consistent(pdev, STATUS_LE_BYTES, &hw->st_dma); | 4439 | hw->st_le = pci_alloc_consistent(pdev, STATUS_LE_BYTES, &hw->st_dma); |
4361 | if (!hw->st_le) | 4440 | if (!hw->st_le) |
@@ -4370,8 +4449,6 @@ static int __devinit sky2_probe(struct pci_dev *pdev, | |||
4370 | 4449 | ||
4371 | sky2_reset(hw); | 4450 | sky2_reset(hw); |
4372 | 4451 | ||
4373 | sky2_vpd_info(hw); | ||
4374 | |||
4375 | dev = sky2_init_netdev(hw, 0, using_dac, wol_default); | 4452 | dev = sky2_init_netdev(hw, 0, using_dac, wol_default); |
4376 | if (!dev) { | 4453 | if (!dev) { |
4377 | err = -ENOMEM; | 4454 | err = -ENOMEM; |