aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/pcmcia/ipwireless/hardware.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/pcmcia/ipwireless/hardware.c')
-rw-r--r--drivers/char/pcmcia/ipwireless/hardware.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/drivers/char/pcmcia/ipwireless/hardware.c b/drivers/char/pcmcia/ipwireless/hardware.c
index fa9d3c945f31..929101ecbae2 100644
--- a/drivers/char/pcmcia/ipwireless/hardware.c
+++ b/drivers/char/pcmcia/ipwireless/hardware.c
@@ -251,10 +251,11 @@ struct ipw_hardware {
251 int init_loops; 251 int init_loops;
252 struct timer_list setup_timer; 252 struct timer_list setup_timer;
253 253
254 /* Flag if hw is ready to send next packet */
254 int tx_ready; 255 int tx_ready;
255 struct list_head tx_queue[NL_NUM_OF_PRIORITIES]; 256 /* Count of pending packets to be sent */
256 /* True if any packets are queued for transmission */
257 int tx_queued; 257 int tx_queued;
258 struct list_head tx_queue[NL_NUM_OF_PRIORITIES];
258 259
259 int rx_bytes_queued; 260 int rx_bytes_queued;
260 struct list_head rx_queue; 261 struct list_head rx_queue;
@@ -404,6 +405,8 @@ static int do_send_fragment(struct ipw_hardware *hw, const unsigned char *data,
404 405
405 spin_lock_irqsave(&hw->spinlock, flags); 406 spin_lock_irqsave(&hw->spinlock, flags);
406 407
408 hw->tx_ready = 0;
409
407 if (hw->hw_version == HW_VERSION_1) { 410 if (hw->hw_version == HW_VERSION_1) {
408 outw((unsigned short) length, hw->base_port + IODWR); 411 outw((unsigned short) length, hw->base_port + IODWR);
409 412
@@ -492,6 +495,7 @@ static int do_send_packet(struct ipw_hardware *hw, struct ipw_tx_packet *packet)
492 495
493 spin_lock_irqsave(&hw->spinlock, flags); 496 spin_lock_irqsave(&hw->spinlock, flags);
494 list_add(&packet->queue, &hw->tx_queue[0]); 497 list_add(&packet->queue, &hw->tx_queue[0]);
498 hw->tx_queued++;
495 spin_unlock_irqrestore(&hw->spinlock, flags); 499 spin_unlock_irqrestore(&hw->spinlock, flags);
496 } else { 500 } else {
497 if (packet->packet_callback) 501 if (packet->packet_callback)
@@ -586,8 +590,10 @@ static struct ipw_rx_packet *pool_allocate(struct ipw_hardware *hw,
586 packet = kmalloc(sizeof(struct ipw_rx_packet) + 590 packet = kmalloc(sizeof(struct ipw_rx_packet) +
587 old_packet->length + minimum_free_space, 591 old_packet->length + minimum_free_space,
588 GFP_ATOMIC); 592 GFP_ATOMIC);
589 if (!packet) 593 if (!packet) {
594 kfree(old_packet);
590 return NULL; 595 return NULL;
596 }
591 memcpy(packet, old_packet, 597 memcpy(packet, old_packet,
592 sizeof(struct ipw_rx_packet) 598 sizeof(struct ipw_rx_packet)
593 + old_packet->length); 599 + old_packet->length);
@@ -949,12 +955,10 @@ static int send_pending_packet(struct ipw_hardware *hw, int priority_limit)
949 unsigned long flags; 955 unsigned long flags;
950 956
951 spin_lock_irqsave(&hw->spinlock, flags); 957 spin_lock_irqsave(&hw->spinlock, flags);
952 if (hw->tx_queued && hw->tx_ready != 0) { 958 if (hw->tx_queued && hw->tx_ready) {
953 int priority; 959 int priority;
954 struct ipw_tx_packet *packet = NULL; 960 struct ipw_tx_packet *packet = NULL;
955 961
956 hw->tx_ready--;
957
958 /* Pick a packet */ 962 /* Pick a packet */
959 for (priority = 0; priority < priority_limit; priority++) { 963 for (priority = 0; priority < priority_limit; priority++) {
960 if (!list_empty(&hw->tx_queue[priority])) { 964 if (!list_empty(&hw->tx_queue[priority])) {
@@ -963,6 +967,7 @@ static int send_pending_packet(struct ipw_hardware *hw, int priority_limit)
963 struct ipw_tx_packet, 967 struct ipw_tx_packet,
964 queue); 968 queue);
965 969
970 hw->tx_queued--;
966 list_del(&packet->queue); 971 list_del(&packet->queue);
967 972
968 break; 973 break;
@@ -973,6 +978,7 @@ static int send_pending_packet(struct ipw_hardware *hw, int priority_limit)
973 spin_unlock_irqrestore(&hw->spinlock, flags); 978 spin_unlock_irqrestore(&hw->spinlock, flags);
974 return 0; 979 return 0;
975 } 980 }
981
976 spin_unlock_irqrestore(&hw->spinlock, flags); 982 spin_unlock_irqrestore(&hw->spinlock, flags);
977 983
978 /* Send */ 984 /* Send */
@@ -1063,7 +1069,7 @@ static irqreturn_t ipwireless_handle_v1_interrupt(int irq,
1063 if (irqn & IR_TXINTR) { 1069 if (irqn & IR_TXINTR) {
1064 ack |= IR_TXINTR; 1070 ack |= IR_TXINTR;
1065 spin_lock_irqsave(&hw->spinlock, flags); 1071 spin_lock_irqsave(&hw->spinlock, flags);
1066 hw->tx_ready++; 1072 hw->tx_ready = 1;
1067 spin_unlock_irqrestore(&hw->spinlock, flags); 1073 spin_unlock_irqrestore(&hw->spinlock, flags);
1068 } 1074 }
1069 /* Received data */ 1075 /* Received data */
@@ -1170,7 +1176,7 @@ static irqreturn_t ipwireless_handle_v2_v3_interrupt(int irq,
1170 if (memrxdone & MEMRX_RX_DONE) { 1176 if (memrxdone & MEMRX_RX_DONE) {
1171 writew(0, &hw->memory_info_regs->memreg_rx_done); 1177 writew(0, &hw->memory_info_regs->memreg_rx_done);
1172 spin_lock_irqsave(&hw->spinlock, flags); 1178 spin_lock_irqsave(&hw->spinlock, flags);
1173 hw->tx_ready++; 1179 hw->tx_ready = 1;
1174 spin_unlock_irqrestore(&hw->spinlock, flags); 1180 spin_unlock_irqrestore(&hw->spinlock, flags);
1175 tx = 1; 1181 tx = 1;
1176 } 1182 }
@@ -1234,7 +1240,7 @@ static void send_packet(struct ipw_hardware *hw, int priority,
1234 1240
1235 spin_lock_irqsave(&hw->spinlock, flags); 1241 spin_lock_irqsave(&hw->spinlock, flags);
1236 list_add_tail(&packet->queue, &hw->tx_queue[priority]); 1242 list_add_tail(&packet->queue, &hw->tx_queue[priority]);
1237 hw->tx_queued = 1; 1243 hw->tx_queued++;
1238 spin_unlock_irqrestore(&hw->spinlock, flags); 1244 spin_unlock_irqrestore(&hw->spinlock, flags);
1239 1245
1240 flush_packets_to_hw(hw); 1246 flush_packets_to_hw(hw);