aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xdrivers/net/qla3xxx.c64
-rwxr-xr-xdrivers/net/qla3xxx.h2
2 files changed, 47 insertions, 19 deletions
diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c
index 5bf446f7be15..e44e8504904b 100755
--- a/drivers/net/qla3xxx.c
+++ b/drivers/net/qla3xxx.c
@@ -1747,8 +1747,31 @@ static void ql_process_mac_tx_intr(struct ql3_adapter *qdev,
1747{ 1747{
1748 struct ql_tx_buf_cb *tx_cb; 1748 struct ql_tx_buf_cb *tx_cb;
1749 int i; 1749 int i;
1750 int retval = 0;
1750 1751
1752 if(mac_rsp->flags & OB_MAC_IOCB_RSP_S) {
1753 printk(KERN_WARNING "Frame short but, frame was padded and sent.\n");
1754 }
1755
1751 tx_cb = &qdev->tx_buf[mac_rsp->transaction_id]; 1756 tx_cb = &qdev->tx_buf[mac_rsp->transaction_id];
1757
1758 /* Check the transmit response flags for any errors */
1759 if(mac_rsp->flags & OB_MAC_IOCB_RSP_S) {
1760 printk(KERN_ERR "Frame too short to be legal, frame not sent.\n");
1761
1762 qdev->stats.tx_errors++;
1763 retval = -EIO;
1764 goto frame_not_sent;
1765 }
1766
1767 if(tx_cb->seg_count == 0) {
1768 printk(KERN_ERR "tx_cb->seg_count == 0: %d\n", mac_rsp->transaction_id);
1769
1770 qdev->stats.tx_errors++;
1771 retval = -EIO;
1772 goto invalid_seg_count;
1773 }
1774
1752 pci_unmap_single(qdev->pdev, 1775 pci_unmap_single(qdev->pdev,
1753 pci_unmap_addr(&tx_cb->map[0], mapaddr), 1776 pci_unmap_addr(&tx_cb->map[0], mapaddr),
1754 pci_unmap_len(&tx_cb->map[0], maplen), 1777 pci_unmap_len(&tx_cb->map[0], maplen),
@@ -1765,8 +1788,12 @@ static void ql_process_mac_tx_intr(struct ql3_adapter *qdev,
1765 } 1788 }
1766 qdev->stats.tx_packets++; 1789 qdev->stats.tx_packets++;
1767 qdev->stats.tx_bytes += tx_cb->skb->len; 1790 qdev->stats.tx_bytes += tx_cb->skb->len;
1791
1792frame_not_sent:
1768 dev_kfree_skb_irq(tx_cb->skb); 1793 dev_kfree_skb_irq(tx_cb->skb);
1769 tx_cb->skb = NULL; 1794 tx_cb->skb = NULL;
1795
1796invalid_seg_count:
1770 atomic_inc(&qdev->tx_count); 1797 atomic_inc(&qdev->tx_count);
1771} 1798}
1772 1799
@@ -1923,8 +1950,10 @@ static int ql_tx_rx_clean(struct ql3_adapter *qdev,
1923 unsigned long hw_flags; 1950 unsigned long hw_flags;
1924 int work_done = 0; 1951 int work_done = 0;
1925 1952
1953 u32 rsp_producer_index = le32_to_cpu(*(qdev->prsp_producer_index));
1954
1926 /* While there are entries in the completion queue. */ 1955 /* While there are entries in the completion queue. */
1927 while ((cpu_to_le32(*(qdev->prsp_producer_index)) != 1956 while ((rsp_producer_index !=
1928 qdev->rsp_consumer_index) && (work_done < work_to_do)) { 1957 qdev->rsp_consumer_index) && (work_done < work_to_do)) {
1929 1958
1930 net_rsp = qdev->rsp_current; 1959 net_rsp = qdev->rsp_current;
@@ -2004,13 +2033,6 @@ static int ql_tx_rx_clean(struct ql3_adapter *qdev,
2004 } 2033 }
2005 2034
2006 spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); 2035 spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
2007
2008 if (unlikely(netif_queue_stopped(qdev->ndev))) {
2009 if (netif_queue_stopped(qdev->ndev) &&
2010 (atomic_read(&qdev->tx_count) >
2011 (NUM_REQ_Q_ENTRIES / 4)))
2012 netif_wake_queue(qdev->ndev);
2013 }
2014 } 2036 }
2015 2037
2016 return *tx_cleaned + *rx_cleaned; 2038 return *tx_cleaned + *rx_cleaned;
@@ -2031,7 +2053,8 @@ static int ql_poll(struct net_device *ndev, int *budget)
2031 *budget -= rx_cleaned; 2053 *budget -= rx_cleaned;
2032 ndev->quota -= rx_cleaned; 2054 ndev->quota -= rx_cleaned;
2033 2055
2034 if ((!tx_cleaned && !rx_cleaned) || !netif_running(ndev)) { 2056 if( tx_cleaned + rx_cleaned != work_to_do ||
2057 !netif_running(ndev)) {
2035quit_polling: 2058quit_polling:
2036 netif_rx_complete(ndev); 2059 netif_rx_complete(ndev);
2037 2060
@@ -2093,8 +2116,8 @@ static irqreturn_t ql3xxx_isr(int irq, void *dev_id)
2093 queue_delayed_work(qdev->workqueue, &qdev->reset_work, 0); 2116 queue_delayed_work(qdev->workqueue, &qdev->reset_work, 0);
2094 spin_unlock(&qdev->adapter_lock); 2117 spin_unlock(&qdev->adapter_lock);
2095 } else if (value & ISP_IMR_DISABLE_CMPL_INT) { 2118 } else if (value & ISP_IMR_DISABLE_CMPL_INT) {
2119 ql_disable_interrupts(qdev);
2096 if (likely(netif_rx_schedule_prep(ndev))) { 2120 if (likely(netif_rx_schedule_prep(ndev))) {
2097 ql_disable_interrupts(qdev);
2098 __netif_rx_schedule(ndev); 2121 __netif_rx_schedule(ndev);
2099 } 2122 }
2100 } else { 2123 } else {
@@ -2113,8 +2136,12 @@ static irqreturn_t ql3xxx_isr(int irq, void *dev_id)
2113 * the next AOL if more frags are coming. 2136 * the next AOL if more frags are coming.
2114 * That is why the frags:segment count ratio is not linear. 2137 * That is why the frags:segment count ratio is not linear.
2115 */ 2138 */
2116static int ql_get_seg_count(unsigned short frags) 2139static int ql_get_seg_count(struct ql3_adapter *qdev,
2140 unsigned short frags)
2117{ 2141{
2142 if (qdev->device_id == QL3022_DEVICE_ID)
2143 return 1;
2144
2118 switch(frags) { 2145 switch(frags) {
2119 case 0: return 1; /* just the skb->data seg */ 2146 case 0: return 1; /* just the skb->data seg */
2120 case 1: return 2; /* skb->data + 1 frag */ 2147 case 1: return 2; /* skb->data + 1 frag */
@@ -2183,14 +2210,15 @@ static int ql_send_map(struct ql3_adapter *qdev,
2183{ 2210{
2184 struct oal *oal; 2211 struct oal *oal;
2185 struct oal_entry *oal_entry; 2212 struct oal_entry *oal_entry;
2186 int len = skb_headlen(skb); 2213 int len = skb->len;
2187 dma_addr_t map; 2214 dma_addr_t map;
2188 int err; 2215 int err;
2189 int completed_segs, i; 2216 int completed_segs, i;
2190 int seg_cnt, seg = 0; 2217 int seg_cnt, seg = 0;
2191 int frag_cnt = (int)skb_shinfo(skb)->nr_frags; 2218 int frag_cnt = (int)skb_shinfo(skb)->nr_frags;
2192 2219
2193 seg_cnt = tx_cb->seg_count = ql_get_seg_count((skb_shinfo(skb)->nr_frags)); 2220 seg_cnt = tx_cb->seg_count = ql_get_seg_count(qdev,
2221 (skb_shinfo(skb)->nr_frags));
2194 if(seg_cnt == -1) { 2222 if(seg_cnt == -1) {
2195 printk(KERN_ERR PFX"%s: invalid segment count!\n",__func__); 2223 printk(KERN_ERR PFX"%s: invalid segment count!\n",__func__);
2196 return NETDEV_TX_BUSY; 2224 return NETDEV_TX_BUSY;
@@ -2216,7 +2244,7 @@ static int ql_send_map(struct ql3_adapter *qdev,
2216 pci_unmap_len_set(&tx_cb->map[seg], maplen, len); 2244 pci_unmap_len_set(&tx_cb->map[seg], maplen, len);
2217 seg++; 2245 seg++;
2218 2246
2219 if (!skb_shinfo(skb)->nr_frags) { 2247 if (seg_cnt == 1) {
2220 /* Terminate the last segment. */ 2248 /* Terminate the last segment. */
2221 oal_entry->len = 2249 oal_entry->len =
2222 cpu_to_le32(le32_to_cpu(oal_entry->len) | OAL_LAST_ENTRY); 2250 cpu_to_le32(le32_to_cpu(oal_entry->len) | OAL_LAST_ENTRY);
@@ -2341,13 +2369,12 @@ static int ql3xxx_send(struct sk_buff *skb, struct net_device *ndev)
2341 struct ob_mac_iocb_req *mac_iocb_ptr; 2369 struct ob_mac_iocb_req *mac_iocb_ptr;
2342 2370
2343 if (unlikely(atomic_read(&qdev->tx_count) < 2)) { 2371 if (unlikely(atomic_read(&qdev->tx_count) < 2)) {
2344 if (!netif_queue_stopped(ndev))
2345 netif_stop_queue(ndev);
2346 return NETDEV_TX_BUSY; 2372 return NETDEV_TX_BUSY;
2347 } 2373 }
2348 2374
2349 tx_cb = &qdev->tx_buf[qdev->req_producer_index] ; 2375 tx_cb = &qdev->tx_buf[qdev->req_producer_index] ;
2350 if((tx_cb->seg_count = ql_get_seg_count((skb_shinfo(skb)->nr_frags))) == -1) { 2376 if((tx_cb->seg_count = ql_get_seg_count(qdev,
2377 (skb_shinfo(skb)->nr_frags))) == -1) {
2351 printk(KERN_ERR PFX"%s: invalid segment count!\n",__func__); 2378 printk(KERN_ERR PFX"%s: invalid segment count!\n",__func__);
2352 return NETDEV_TX_OK; 2379 return NETDEV_TX_OK;
2353 } 2380 }
@@ -2359,7 +2386,8 @@ static int ql3xxx_send(struct sk_buff *skb, struct net_device *ndev)
2359 mac_iocb_ptr->transaction_id = qdev->req_producer_index; 2386 mac_iocb_ptr->transaction_id = qdev->req_producer_index;
2360 mac_iocb_ptr->data_len = cpu_to_le16((u16) tot_len); 2387 mac_iocb_ptr->data_len = cpu_to_le16((u16) tot_len);
2361 tx_cb->skb = skb; 2388 tx_cb->skb = skb;
2362 if (skb->ip_summed == CHECKSUM_PARTIAL) 2389 if (qdev->device_id == QL3032_DEVICE_ID &&
2390 skb->ip_summed == CHECKSUM_PARTIAL)
2363 ql_hw_csum_setup(skb, mac_iocb_ptr); 2391 ql_hw_csum_setup(skb, mac_iocb_ptr);
2364 2392
2365 if(ql_send_map(qdev,mac_iocb_ptr,tx_cb,skb) != NETDEV_TX_OK) { 2393 if(ql_send_map(qdev,mac_iocb_ptr,tx_cb,skb) != NETDEV_TX_OK) {
diff --git a/drivers/net/qla3xxx.h b/drivers/net/qla3xxx.h
index 40913d2c7097..34cd6580fd07 100755
--- a/drivers/net/qla3xxx.h
+++ b/drivers/net/qla3xxx.h
@@ -1194,7 +1194,7 @@ struct ql3_adapter {
1194 struct net_rsp_iocb *rsp_current; 1194 struct net_rsp_iocb *rsp_current;
1195 u16 rsp_consumer_index; 1195 u16 rsp_consumer_index;
1196 u16 reserved_06; 1196 u16 reserved_06;
1197 u32 *prsp_producer_index; 1197 volatile u32 *prsp_producer_index;
1198 u32 rsp_producer_index_phy_addr_high; 1198 u32 rsp_producer_index_phy_addr_high;
1199 u32 rsp_producer_index_phy_addr_low; 1199 u32 rsp_producer_index_phy_addr_low;
1200 1200