aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ipg.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ipg.c')
-rw-r--r--drivers/net/ipg.c105
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
46enum { 45enum {
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");
55MODULE_LICENSE("GPL"); 54MODULE_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
632static int ipg_io_config(struct net_device *dev) 639static 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
1100inline void ipg_nic_rx_free_skb(struct net_device *dev) 1106static 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
1116inline int ipg_nic_rx_check_frame_type(struct net_device *dev) 1122static 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
1129inline int ipg_nic_rx_check_error(struct net_device *dev) 1135static 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
1337static int ipg_nic_rx(struct net_device *dev) 1339static 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
1386static int ipg_nic_rx(struct net_device *dev) 1387static 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
1561static void ipg_reset_after_host_error(struct work_struct *work) 1561static 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
2120static int ipg_nic_change_mtu(struct net_device *dev, int new_mtu) 2120static 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
2141static int ipg_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) 2161static 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;