diff options
Diffstat (limited to 'drivers/net/ipg.c')
-rw-r--r-- | drivers/net/ipg.c | 105 |
1 files changed, 65 insertions, 40 deletions
diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c index 2c03f4e2ccc4..7373dafbb3f7 100644 --- a/drivers/net/ipg.c +++ b/drivers/net/ipg.c | |||
@@ -42,7 +42,6 @@ | |||
42 | #define ipg_r16(reg) ioread16(ioaddr + (reg)) | 42 | #define ipg_r16(reg) ioread16(ioaddr + (reg)) |
43 | #define ipg_r8(reg) ioread8(ioaddr + (reg)) | 43 | #define ipg_r8(reg) ioread8(ioaddr + (reg)) |
44 | 44 | ||
45 | #define JUMBO_FRAME_4k_ONLY | ||
46 | enum { | 45 | enum { |
47 | netdev_io_size = 128 | 46 | netdev_io_size = 128 |
48 | }; | 47 | }; |
@@ -55,6 +54,14 @@ MODULE_DESCRIPTION("IC Plus IP1000 Gigabit Ethernet Adapter Linux Driver"); | |||
55 | MODULE_LICENSE("GPL"); | 54 | MODULE_LICENSE("GPL"); |
56 | 55 | ||
57 | /* | 56 | /* |
57 | * Defaults | ||
58 | */ | ||
59 | #define IPG_MAX_RXFRAME_SIZE 0x0600 | ||
60 | #define IPG_RXFRAG_SIZE 0x0600 | ||
61 | #define IPG_RXSUPPORT_SIZE 0x0600 | ||
62 | #define IPG_IS_JUMBO false | ||
63 | |||
64 | /* | ||
58 | * Variable record -- index by leading revision/length | 65 | * Variable record -- index by leading revision/length |
59 | * Revision/Length(=N*4), Address1, Data1, Address2, Data2,...,AddressN,DataN | 66 | * Revision/Length(=N*4), Address1, Data1, Address2, Data2,...,AddressN,DataN |
60 | */ | 67 | */ |
@@ -631,6 +638,7 @@ static void ipg_nic_set_multicast_list(struct net_device *dev) | |||
631 | 638 | ||
632 | static int ipg_io_config(struct net_device *dev) | 639 | static int ipg_io_config(struct net_device *dev) |
633 | { | 640 | { |
641 | struct ipg_nic_private *sp = netdev_priv(dev); | ||
634 | void __iomem *ioaddr = ipg_ioaddr(dev); | 642 | void __iomem *ioaddr = ipg_ioaddr(dev); |
635 | u32 origmacctrl; | 643 | u32 origmacctrl; |
636 | u32 restoremacctrl; | 644 | u32 restoremacctrl; |
@@ -670,7 +678,7 @@ static int ipg_io_config(struct net_device *dev) | |||
670 | /* Set RECEIVEMODE register. */ | 678 | /* Set RECEIVEMODE register. */ |
671 | ipg_nic_set_multicast_list(dev); | 679 | ipg_nic_set_multicast_list(dev); |
672 | 680 | ||
673 | ipg_w16(IPG_MAX_RXFRAME_SIZE, MAX_FRAME_SIZE); | 681 | ipg_w16(sp->max_rxframe_size, MAX_FRAME_SIZE); |
674 | 682 | ||
675 | ipg_w8(IPG_RXDMAPOLLPERIOD_VALUE, RX_DMA_POLL_PERIOD); | 683 | ipg_w8(IPG_RXDMAPOLLPERIOD_VALUE, RX_DMA_POLL_PERIOD); |
676 | ipg_w8(IPG_RXDMAURGENTTHRESH_VALUE, RX_DMA_URGENT_THRESH); | 684 | ipg_w8(IPG_RXDMAURGENTTHRESH_VALUE, RX_DMA_URGENT_THRESH); |
@@ -730,7 +738,7 @@ static int ipg_get_rxbuff(struct net_device *dev, int entry) | |||
730 | 738 | ||
731 | IPG_DEBUG_MSG("_get_rxbuff\n"); | 739 | IPG_DEBUG_MSG("_get_rxbuff\n"); |
732 | 740 | ||
733 | skb = netdev_alloc_skb(dev, IPG_RXSUPPORT_SIZE + NET_IP_ALIGN); | 741 | skb = netdev_alloc_skb(dev, sp->rxsupport_size + NET_IP_ALIGN); |
734 | if (!skb) { | 742 | if (!skb) { |
735 | sp->rx_buff[entry] = NULL; | 743 | sp->rx_buff[entry] = NULL; |
736 | return -ENOMEM; | 744 | return -ENOMEM; |
@@ -751,7 +759,7 @@ static int ipg_get_rxbuff(struct net_device *dev, int entry) | |||
751 | sp->rx_buf_sz, PCI_DMA_FROMDEVICE)); | 759 | sp->rx_buf_sz, PCI_DMA_FROMDEVICE)); |
752 | 760 | ||
753 | /* Set the RFD fragment length. */ | 761 | /* Set the RFD fragment length. */ |
754 | rxfragsize = IPG_RXFRAG_SIZE; | 762 | rxfragsize = sp->rxfrag_size; |
755 | rxfd->frag_info |= cpu_to_le64((rxfragsize << 48) & IPG_RFI_FRAGLEN); | 763 | rxfd->frag_info |= cpu_to_le64((rxfragsize << 48) & IPG_RFI_FRAGLEN); |
756 | 764 | ||
757 | return 0; | 765 | return 0; |
@@ -1076,8 +1084,6 @@ static int ipg_nic_rxrestore(struct net_device *dev) | |||
1076 | return 0; | 1084 | return 0; |
1077 | } | 1085 | } |
1078 | 1086 | ||
1079 | #ifdef JUMBO_FRAME | ||
1080 | |||
1081 | /* use jumboindex and jumbosize to control jumbo frame status | 1087 | /* use jumboindex and jumbosize to control jumbo frame status |
1082 | * initial status is jumboindex=-1 and jumbosize=0 | 1088 | * initial status is jumboindex=-1 and jumbosize=0 |
1083 | * 1. jumboindex = -1 and jumbosize=0 : previous jumbo frame has been done. | 1089 | * 1. jumboindex = -1 and jumbosize=0 : previous jumbo frame has been done. |
@@ -1097,7 +1103,7 @@ enum { | |||
1097 | FRAME_WITH_START_WITH_END = 11 | 1103 | FRAME_WITH_START_WITH_END = 11 |
1098 | }; | 1104 | }; |
1099 | 1105 | ||
1100 | inline void ipg_nic_rx_free_skb(struct net_device *dev) | 1106 | static void ipg_nic_rx_free_skb(struct net_device *dev) |
1101 | { | 1107 | { |
1102 | struct ipg_nic_private *sp = netdev_priv(dev); | 1108 | struct ipg_nic_private *sp = netdev_priv(dev); |
1103 | unsigned int entry = sp->rx_current % IPG_RFDLIST_LENGTH; | 1109 | unsigned int entry = sp->rx_current % IPG_RFDLIST_LENGTH; |
@@ -1113,7 +1119,7 @@ inline void ipg_nic_rx_free_skb(struct net_device *dev) | |||
1113 | } | 1119 | } |
1114 | } | 1120 | } |
1115 | 1121 | ||
1116 | inline int ipg_nic_rx_check_frame_type(struct net_device *dev) | 1122 | static int ipg_nic_rx_check_frame_type(struct net_device *dev) |
1117 | { | 1123 | { |
1118 | struct ipg_nic_private *sp = netdev_priv(dev); | 1124 | struct ipg_nic_private *sp = netdev_priv(dev); |
1119 | struct ipg_rx *rxfd = sp->rxd + (sp->rx_current % IPG_RFDLIST_LENGTH); | 1125 | struct ipg_rx *rxfd = sp->rxd + (sp->rx_current % IPG_RFDLIST_LENGTH); |
@@ -1126,7 +1132,7 @@ inline int ipg_nic_rx_check_frame_type(struct net_device *dev) | |||
1126 | return type; | 1132 | return type; |
1127 | } | 1133 | } |
1128 | 1134 | ||
1129 | inline int ipg_nic_rx_check_error(struct net_device *dev) | 1135 | static int ipg_nic_rx_check_error(struct net_device *dev) |
1130 | { | 1136 | { |
1131 | struct ipg_nic_private *sp = netdev_priv(dev); | 1137 | struct ipg_nic_private *sp = netdev_priv(dev); |
1132 | unsigned int entry = sp->rx_current % IPG_RFDLIST_LENGTH; | 1138 | unsigned int entry = sp->rx_current % IPG_RFDLIST_LENGTH; |
@@ -1209,8 +1215,8 @@ static void ipg_nic_rx_with_start_and_end(struct net_device *dev, | |||
1209 | 1215 | ||
1210 | /* accept this frame and send to upper layer */ | 1216 | /* accept this frame and send to upper layer */ |
1211 | framelen = le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFRAMELEN; | 1217 | framelen = le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFRAMELEN; |
1212 | if (framelen > IPG_RXFRAG_SIZE) | 1218 | if (framelen > sp->rxfrag_size) |
1213 | framelen = IPG_RXFRAG_SIZE; | 1219 | framelen = sp->rxfrag_size; |
1214 | 1220 | ||
1215 | skb_put(skb, framelen); | 1221 | skb_put(skb, framelen); |
1216 | skb->protocol = eth_type_trans(skb, dev); | 1222 | skb->protocol = eth_type_trans(skb, dev); |
@@ -1243,10 +1249,10 @@ static void ipg_nic_rx_with_start(struct net_device *dev, | |||
1243 | pci_unmap_single(pdev, le64_to_cpu(rxfd->frag_info & ~IPG_RFI_FRAGLEN), | 1249 | pci_unmap_single(pdev, le64_to_cpu(rxfd->frag_info & ~IPG_RFI_FRAGLEN), |
1244 | sp->rx_buf_sz, PCI_DMA_FROMDEVICE); | 1250 | sp->rx_buf_sz, PCI_DMA_FROMDEVICE); |
1245 | 1251 | ||
1246 | skb_put(skb, IPG_RXFRAG_SIZE); | 1252 | skb_put(skb, sp->rxfrag_size); |
1247 | 1253 | ||
1248 | jumbo->found_start = 1; | 1254 | jumbo->found_start = 1; |
1249 | jumbo->current_size = IPG_RXFRAG_SIZE; | 1255 | jumbo->current_size = sp->rxfrag_size; |
1250 | jumbo->skb = skb; | 1256 | jumbo->skb = skb; |
1251 | 1257 | ||
1252 | sp->rx_buff[entry] = NULL; | 1258 | sp->rx_buff[entry] = NULL; |
@@ -1272,11 +1278,7 @@ static void ipg_nic_rx_with_end(struct net_device *dev, | |||
1272 | framelen = le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFRAMELEN; | 1278 | framelen = le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFRAMELEN; |
1273 | 1279 | ||
1274 | endframelen = framelen - jumbo->current_size; | 1280 | endframelen = framelen - jumbo->current_size; |
1275 | /* | 1281 | if (framelen > sp->rxsupport_size) |
1276 | if (framelen > IPG_RXFRAG_SIZE) | ||
1277 | framelen=IPG_RXFRAG_SIZE; | ||
1278 | */ | ||
1279 | if (framelen > IPG_RXSUPPORT_SIZE) | ||
1280 | dev_kfree_skb_irq(jumbo->skb); | 1282 | dev_kfree_skb_irq(jumbo->skb); |
1281 | else { | 1283 | else { |
1282 | memcpy(skb_put(jumbo->skb, endframelen), | 1284 | memcpy(skb_put(jumbo->skb, endframelen), |
@@ -1316,11 +1318,11 @@ static void ipg_nic_rx_no_start_no_end(struct net_device *dev, | |||
1316 | 1318 | ||
1317 | if (skb) { | 1319 | if (skb) { |
1318 | if (jumbo->found_start) { | 1320 | if (jumbo->found_start) { |
1319 | jumbo->current_size += IPG_RXFRAG_SIZE; | 1321 | jumbo->current_size += sp->rxfrag_size; |
1320 | if (jumbo->current_size <= IPG_RXSUPPORT_SIZE) { | 1322 | if (jumbo->current_size <= sp->rxsupport_size) { |
1321 | memcpy(skb_put(jumbo->skb, | 1323 | memcpy(skb_put(jumbo->skb, |
1322 | IPG_RXFRAG_SIZE), | 1324 | sp->rxfrag_size), |
1323 | skb->data, IPG_RXFRAG_SIZE); | 1325 | skb->data, sp->rxfrag_size); |
1324 | } | 1326 | } |
1325 | } | 1327 | } |
1326 | dev->last_rx = jiffies; | 1328 | dev->last_rx = jiffies; |
@@ -1334,7 +1336,7 @@ static void ipg_nic_rx_no_start_no_end(struct net_device *dev, | |||
1334 | } | 1336 | } |
1335 | } | 1337 | } |
1336 | 1338 | ||
1337 | static int ipg_nic_rx(struct net_device *dev) | 1339 | static int ipg_nic_rx_jumbo(struct net_device *dev) |
1338 | { | 1340 | { |
1339 | struct ipg_nic_private *sp = netdev_priv(dev); | 1341 | struct ipg_nic_private *sp = netdev_priv(dev); |
1340 | unsigned int curr = sp->rx_current; | 1342 | unsigned int curr = sp->rx_current; |
@@ -1382,7 +1384,6 @@ static int ipg_nic_rx(struct net_device *dev) | |||
1382 | return 0; | 1384 | return 0; |
1383 | } | 1385 | } |
1384 | 1386 | ||
1385 | #else | ||
1386 | static int ipg_nic_rx(struct net_device *dev) | 1387 | static int ipg_nic_rx(struct net_device *dev) |
1387 | { | 1388 | { |
1388 | /* Transfer received Ethernet frames to higher network layers. */ | 1389 | /* Transfer received Ethernet frames to higher network layers. */ |
@@ -1413,11 +1414,11 @@ static int ipg_nic_rx(struct net_device *dev) | |||
1413 | /* Check for jumbo frame arrival with too small | 1414 | /* Check for jumbo frame arrival with too small |
1414 | * RXFRAG_SIZE. | 1415 | * RXFRAG_SIZE. |
1415 | */ | 1416 | */ |
1416 | if (framelen > IPG_RXFRAG_SIZE) { | 1417 | if (framelen > sp->rxfrag_size) { |
1417 | IPG_DEBUG_MSG | 1418 | IPG_DEBUG_MSG |
1418 | ("RFS FrameLen > allocated fragment size.\n"); | 1419 | ("RFS FrameLen > allocated fragment size.\n"); |
1419 | 1420 | ||
1420 | framelen = IPG_RXFRAG_SIZE; | 1421 | framelen = sp->rxfrag_size; |
1421 | } | 1422 | } |
1422 | 1423 | ||
1423 | if ((IPG_DROP_ON_RX_ETH_ERRORS && (le64_to_cpu(rxfd->rfs) & | 1424 | if ((IPG_DROP_ON_RX_ETH_ERRORS && (le64_to_cpu(rxfd->rfs) & |
@@ -1556,7 +1557,6 @@ static int ipg_nic_rx(struct net_device *dev) | |||
1556 | 1557 | ||
1557 | return 0; | 1558 | return 0; |
1558 | } | 1559 | } |
1559 | #endif | ||
1560 | 1560 | ||
1561 | static void ipg_reset_after_host_error(struct work_struct *work) | 1561 | static void ipg_reset_after_host_error(struct work_struct *work) |
1562 | { | 1562 | { |
@@ -1592,9 +1592,9 @@ static irqreturn_t ipg_interrupt_handler(int irq, void *dev_inst) | |||
1592 | 1592 | ||
1593 | IPG_DEBUG_MSG("_interrupt_handler\n"); | 1593 | IPG_DEBUG_MSG("_interrupt_handler\n"); |
1594 | 1594 | ||
1595 | #ifdef JUMBO_FRAME | 1595 | if (sp->is_jumbo) |
1596 | ipg_nic_rxrestore(dev); | 1596 | ipg_nic_rxrestore(dev); |
1597 | #endif | 1597 | |
1598 | spin_lock(&sp->lock); | 1598 | spin_lock(&sp->lock); |
1599 | 1599 | ||
1600 | /* Get interrupt source information, and acknowledge | 1600 | /* Get interrupt source information, and acknowledge |
@@ -1650,7 +1650,10 @@ static irqreturn_t ipg_interrupt_handler(int irq, void *dev_inst) | |||
1650 | sp->RFDListCheckedCount++; | 1650 | sp->RFDListCheckedCount++; |
1651 | #endif | 1651 | #endif |
1652 | 1652 | ||
1653 | ipg_nic_rx(dev); | 1653 | if (sp->is_jumbo) |
1654 | ipg_nic_rx_jumbo(dev); | ||
1655 | else | ||
1656 | ipg_nic_rx(dev); | ||
1654 | } | 1657 | } |
1655 | 1658 | ||
1656 | /* If TxDMAComplete interrupt, free used TFDs. */ | 1659 | /* If TxDMAComplete interrupt, free used TFDs. */ |
@@ -1749,7 +1752,7 @@ static int ipg_nic_open(struct net_device *dev) | |||
1749 | 1752 | ||
1750 | IPG_DEBUG_MSG("_nic_open\n"); | 1753 | IPG_DEBUG_MSG("_nic_open\n"); |
1751 | 1754 | ||
1752 | sp->rx_buf_sz = IPG_RXSUPPORT_SIZE; | 1755 | sp->rx_buf_sz = sp->rxsupport_size; |
1753 | 1756 | ||
1754 | /* Check for interrupt line conflicts, and request interrupt | 1757 | /* Check for interrupt line conflicts, and request interrupt |
1755 | * line for IPG. | 1758 | * line for IPG. |
@@ -1804,13 +1807,10 @@ static int ipg_nic_open(struct net_device *dev) | |||
1804 | if (ipg_config_autoneg(dev) < 0) | 1807 | if (ipg_config_autoneg(dev) < 0) |
1805 | printk(KERN_INFO "%s: Auto-negotiation error.\n", dev->name); | 1808 | printk(KERN_INFO "%s: Auto-negotiation error.\n", dev->name); |
1806 | 1809 | ||
1807 | #ifdef JUMBO_FRAME | ||
1808 | /* initialize JUMBO Frame control variable */ | 1810 | /* initialize JUMBO Frame control variable */ |
1809 | sp->jumbo.found_start = 0; | 1811 | sp->jumbo.found_start = 0; |
1810 | sp->jumbo.current_size = 0; | 1812 | sp->jumbo.current_size = 0; |
1811 | sp->jumbo.skb = NULL; | 1813 | sp->jumbo.skb = NULL; |
1812 | dev->mtu = IPG_TXFRAG_SIZE; | ||
1813 | #endif | ||
1814 | 1814 | ||
1815 | /* Enable transmit and receive operation of the IPG. */ | 1815 | /* Enable transmit and receive operation of the IPG. */ |
1816 | ipg_w32((ipg_r32(MAC_CTRL) | IPG_MC_RX_ENABLE | IPG_MC_TX_ENABLE) & | 1816 | ipg_w32((ipg_r32(MAC_CTRL) | IPG_MC_RX_ENABLE | IPG_MC_TX_ENABLE) & |
@@ -2119,6 +2119,9 @@ static int ipg_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
2119 | 2119 | ||
2120 | static int ipg_nic_change_mtu(struct net_device *dev, int new_mtu) | 2120 | static int ipg_nic_change_mtu(struct net_device *dev, int new_mtu) |
2121 | { | 2121 | { |
2122 | struct ipg_nic_private *sp = netdev_priv(dev); | ||
2123 | int err; | ||
2124 | |||
2122 | /* Function to accomodate changes to Maximum Transfer Unit | 2125 | /* Function to accomodate changes to Maximum Transfer Unit |
2123 | * (or MTU) of IPG NIC. Cannot use default function since | 2126 | * (or MTU) of IPG NIC. Cannot use default function since |
2124 | * the default will not allow for MTU > 1500 bytes. | 2127 | * the default will not allow for MTU > 1500 bytes. |
@@ -2126,16 +2129,33 @@ static int ipg_nic_change_mtu(struct net_device *dev, int new_mtu) | |||
2126 | 2129 | ||
2127 | IPG_DEBUG_MSG("_nic_change_mtu\n"); | 2130 | IPG_DEBUG_MSG("_nic_change_mtu\n"); |
2128 | 2131 | ||
2129 | /* Check that the new MTU value is between 68 (14 byte header, 46 | 2132 | /* |
2130 | * byte payload, 4 byte FCS) and IPG_MAX_RXFRAME_SIZE, which | 2133 | * Check that the new MTU value is between 68 (14 byte header, 46 byte |
2131 | * corresponds to the MAXFRAMESIZE register in the IPG. | 2134 | * payload, 4 byte FCS) and 10 KB, which is the largest supported MTU. |
2132 | */ | 2135 | */ |
2133 | if ((new_mtu < 68) || (new_mtu > IPG_MAX_RXFRAME_SIZE)) | 2136 | if (new_mtu < 68 || new_mtu > 10240) |
2134 | return -EINVAL; | 2137 | return -EINVAL; |
2135 | 2138 | ||
2139 | err = ipg_nic_stop(dev); | ||
2140 | if (err) | ||
2141 | return err; | ||
2142 | |||
2136 | dev->mtu = new_mtu; | 2143 | dev->mtu = new_mtu; |
2137 | 2144 | ||
2138 | return 0; | 2145 | sp->max_rxframe_size = new_mtu; |
2146 | |||
2147 | sp->rxfrag_size = new_mtu; | ||
2148 | if (sp->rxfrag_size > 4088) | ||
2149 | sp->rxfrag_size = 4088; | ||
2150 | |||
2151 | sp->rxsupport_size = sp->max_rxframe_size; | ||
2152 | |||
2153 | if (new_mtu > 0x0600) | ||
2154 | sp->is_jumbo = true; | ||
2155 | else | ||
2156 | sp->is_jumbo = false; | ||
2157 | |||
2158 | return ipg_nic_open(dev); | ||
2139 | } | 2159 | } |
2140 | 2160 | ||
2141 | static int ipg_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | 2161 | static int ipg_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) |
@@ -2240,6 +2260,11 @@ static int __devinit ipg_probe(struct pci_dev *pdev, | |||
2240 | spin_lock_init(&sp->lock); | 2260 | spin_lock_init(&sp->lock); |
2241 | mutex_init(&sp->mii_mutex); | 2261 | mutex_init(&sp->mii_mutex); |
2242 | 2262 | ||
2263 | sp->is_jumbo = IPG_IS_JUMBO; | ||
2264 | sp->rxfrag_size = IPG_RXFRAG_SIZE; | ||
2265 | sp->rxsupport_size = IPG_RXSUPPORT_SIZE; | ||
2266 | sp->max_rxframe_size = IPG_MAX_RXFRAME_SIZE; | ||
2267 | |||
2243 | /* Declare IPG NIC functions for Ethernet device methods. | 2268 | /* Declare IPG NIC functions for Ethernet device methods. |
2244 | */ | 2269 | */ |
2245 | dev->open = &ipg_nic_open; | 2270 | dev->open = &ipg_nic_open; |