Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 1 | /** |
Kevin McKinney | b9e25f8 | 2012-09-13 21:11:37 -0400 | [diff] [blame] | 2 | * @file Transmit.c |
| 3 | * @defgroup tx_functions Transmission |
| 4 | * @section Queueing |
| 5 | * @dot |
| 6 | * digraph transmit1 { |
| 7 | * node[shape=box] |
| 8 | * edge[weight=5;color=red] |
| 9 | * |
| 10 | * bcm_transmit->GetPacketQueueIndex[label="IP Packet"] |
| 11 | * GetPacketQueueIndex->IpVersion4[label="IPV4"] |
| 12 | * GetPacketQueueIndex->IpVersion6[label="IPV6"] |
| 13 | * } |
| 14 | * |
| 15 | * @enddot |
| 16 | * |
| 17 | * @section De-Queueing |
| 18 | * @dot |
| 19 | * digraph transmit2 { |
| 20 | * node[shape=box] |
| 21 | * edge[weight=5;color=red] |
| 22 | * interrupt_service_thread->transmit_packets |
| 23 | * tx_pkt_hdler->transmit_packets |
| 24 | * transmit_packets->CheckAndSendPacketFromIndex |
| 25 | * transmit_packets->UpdateTokenCount |
| 26 | * CheckAndSendPacketFromIndex->PruneQueue |
| 27 | * CheckAndSendPacketFromIndex->IsPacketAllowedForFlow |
| 28 | * CheckAndSendPacketFromIndex->SendControlPacket[label="control pkt"] |
| 29 | * SendControlPacket->bcm_cmd53 |
| 30 | * CheckAndSendPacketFromIndex->SendPacketFromQueue[label="data pkt"] |
| 31 | * SendPacketFromQueue->SetupNextSend->bcm_cmd53 |
| 32 | * } |
| 33 | * @enddot |
| 34 | */ |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 35 | |
| 36 | #include "headers.h" |
| 37 | |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 38 | /** |
Kevin McKinney | b9e25f8 | 2012-09-13 21:11:37 -0400 | [diff] [blame] | 39 | * @ingroup ctrl_pkt_functions |
| 40 | * This function dispatches control packet to the h/w interface |
| 41 | * @return zero(success) or -ve value(failure) |
| 42 | */ |
Kevin McKinney | ae1cbea | 2012-09-13 21:11:38 -0400 | [diff] [blame] | 43 | int SendControlPacket(struct bcm_mini_adapter *Adapter, char *pControlPacket) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 44 | { |
Kevin McKinney | ff35204 | 2012-05-26 12:05:11 -0400 | [diff] [blame] | 45 | struct bcm_leader *PLeader = (struct bcm_leader *)pControlPacket; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 46 | |
Kevin McKinney | 22976bc | 2012-09-13 21:11:34 -0400 | [diff] [blame] | 47 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Tx"); |
Kevin McKinney | 97e0a50 | 2012-09-13 21:11:35 -0400 | [diff] [blame] | 48 | if (!pControlPacket || !Adapter) { |
Kevin McKinney | 22976bc | 2012-09-13 21:11:34 -0400 | [diff] [blame] | 49 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Got NULL Control Packet or Adapter"); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 50 | return STATUS_FAILURE; |
| 51 | } |
Kevin McKinney | 22976bc | 2012-09-13 21:11:34 -0400 | [diff] [blame] | 52 | if ((atomic_read(&Adapter->CurrNumFreeTxDesc) < |
Kevin McKinney | 97e0a50 | 2012-09-13 21:11:35 -0400 | [diff] [blame] | 53 | ((PLeader->PLength-1)/MAX_DEVICE_DESC_SIZE)+1)) { |
Kevin McKinney | 22976bc | 2012-09-13 21:11:34 -0400 | [diff] [blame] | 54 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "NO FREE DESCRIPTORS TO SEND CONTROL PACKET"); |
| 55 | return STATUS_FAILURE; |
| 56 | } |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 57 | |
| 58 | /* Update the netdevice statistics */ |
| 59 | /* Dump Packet */ |
Kevin McKinney | 22976bc | 2012-09-13 21:11:34 -0400 | [diff] [blame] | 60 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Status: %x", PLeader->Status); |
| 61 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader VCID: %x", PLeader->Vcid); |
| 62 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Length: %x", PLeader->PLength); |
| 63 | if (Adapter->device_removed) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 64 | return 0; |
Stephen Hemminger | 349fa79 | 2010-11-01 14:09:05 -0400 | [diff] [blame] | 65 | |
| 66 | if (netif_msg_pktdata(Adapter)) |
| 67 | print_hex_dump(KERN_DEBUG, PFX "tx control: ", DUMP_PREFIX_NONE, |
Kevin McKinney | 22976bc | 2012-09-13 21:11:34 -0400 | [diff] [blame] | 68 | 16, 1, pControlPacket, PLeader->PLength + LEADER_SIZE, 0); |
Stephen Hemminger | 349fa79 | 2010-11-01 14:09:05 -0400 | [diff] [blame] | 69 | |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 70 | Adapter->interface_transmit(Adapter->pvInterfaceAdapter, |
Kevin McKinney | 22976bc | 2012-09-13 21:11:34 -0400 | [diff] [blame] | 71 | pControlPacket, (PLeader->PLength + LEADER_SIZE)); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 72 | |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 73 | atomic_dec(&Adapter->CurrNumFreeTxDesc); |
Kevin McKinney | 22976bc | 2012-09-13 21:11:34 -0400 | [diff] [blame] | 74 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "<========="); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 75 | return STATUS_SUCCESS; |
| 76 | } |
Stephen Hemminger | ac1b1ae | 2010-11-01 12:20:09 -0400 | [diff] [blame] | 77 | |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 78 | /** |
Kevin McKinney | b9e25f8 | 2012-09-13 21:11:37 -0400 | [diff] [blame] | 79 | * @ingroup tx_functions |
| 80 | * This function despatches the IP packets with the given vcid |
| 81 | * to the target via the host h/w interface. |
| 82 | * @return zero(success) or -ve value(failure) |
| 83 | */ |
Kevin McKinney | ae1cbea | 2012-09-13 21:11:38 -0400 | [diff] [blame] | 84 | int SetupNextSend(struct bcm_mini_adapter *Adapter, struct sk_buff *Packet, USHORT Vcid) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 85 | { |
Kevin McKinney | 22976bc | 2012-09-13 21:11:34 -0400 | [diff] [blame] | 86 | int status = 0; |
Lisa Nguyen | f70c8a9 | 2013-10-28 01:36:19 -0700 | [diff] [blame] | 87 | bool bHeaderSupressionEnabled = false; |
Kevin McKinney | 22976bc | 2012-09-13 21:11:34 -0400 | [diff] [blame] | 88 | B_UINT16 uiClassifierRuleID; |
Stephen Hemminger | cacd922 | 2010-11-01 13:34:35 -0400 | [diff] [blame] | 89 | u16 QueueIndex = skb_get_queue_mapping(Packet); |
Kevin McKinney | 22976bc | 2012-09-13 21:11:34 -0400 | [diff] [blame] | 90 | struct bcm_leader Leader = {0}; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 91 | |
Kevin McKinney | 97e0a50 | 2012-09-13 21:11:35 -0400 | [diff] [blame] | 92 | if (Packet->len > MAX_DEVICE_DESC_SIZE) { |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 93 | status = STATUS_FAILURE; |
| 94 | goto errExit; |
| 95 | } |
| 96 | |
| 97 | /* Get the Classifier Rule ID */ |
Kevin McKinney | 22976bc | 2012-09-13 21:11:34 -0400 | [diff] [blame] | 98 | uiClassifierRuleID = *((UINT32 *) (Packet->cb) + SKB_CB_CLASSIFICATION_OFFSET); |
Stephen Hemminger | cacd922 | 2010-11-01 13:34:35 -0400 | [diff] [blame] | 99 | |
| 100 | bHeaderSupressionEnabled = Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled |
| 101 | & Adapter->bPHSEnabled; |
| 102 | |
Kevin McKinney | 97e0a50 | 2012-09-13 21:11:35 -0400 | [diff] [blame] | 103 | if (Adapter->device_removed) { |
Kevin McKinney | 22976bc | 2012-09-13 21:11:34 -0400 | [diff] [blame] | 104 | status = STATUS_FAILURE; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 105 | goto errExit; |
| 106 | } |
| 107 | |
Kevin McKinney | 22976bc | 2012-09-13 21:11:34 -0400 | [diff] [blame] | 108 | status = PHSTransmit(Adapter, &Packet, Vcid, uiClassifierRuleID, bHeaderSupressionEnabled, |
| 109 | (UINT *)&Packet->len, Adapter->PackInfo[QueueIndex].bEthCSSupport); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 110 | |
Kevin McKinney | 97e0a50 | 2012-09-13 21:11:35 -0400 | [diff] [blame] | 111 | if (status != STATUS_SUCCESS) { |
Kevin McKinney | 22976bc | 2012-09-13 21:11:34 -0400 | [diff] [blame] | 112 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "PHS Transmit failed..\n"); |
| 113 | goto errExit; |
| 114 | } |
| 115 | |
| 116 | Leader.Vcid = Vcid; |
| 117 | |
| 118 | if (TCP_ACK == *((UINT32 *) (Packet->cb) + SKB_CB_TCPACK_OFFSET)) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 119 | Leader.Status = LEADER_STATUS_TCP_ACK; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 120 | else |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 121 | Leader.Status = LEADER_STATUS; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 122 | |
Kevin McKinney | 97e0a50 | 2012-09-13 21:11:35 -0400 | [diff] [blame] | 123 | if (Adapter->PackInfo[QueueIndex].bEthCSSupport) { |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 124 | Leader.PLength = Packet->len; |
Kevin McKinney | 97e0a50 | 2012-09-13 21:11:35 -0400 | [diff] [blame] | 125 | if (skb_headroom(Packet) < LEADER_SIZE) { |
Kevin McKinney | d5873d3 | 2012-09-13 21:11:36 -0400 | [diff] [blame] | 126 | status = skb_cow(Packet, LEADER_SIZE); |
| 127 | if (status) { |
Kevin McKinney | 22976bc | 2012-09-13 21:11:34 -0400 | [diff] [blame] | 128 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "bcm_transmit : Failed To Increase headRoom\n"); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 129 | goto errExit; |
| 130 | } |
| 131 | } |
| 132 | skb_push(Packet, LEADER_SIZE); |
| 133 | memcpy(Packet->data, &Leader, LEADER_SIZE); |
Kevin McKinney | 97e0a50 | 2012-09-13 21:11:35 -0400 | [diff] [blame] | 134 | } else { |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 135 | Leader.PLength = Packet->len - ETH_HLEN; |
Kevin McKinney | ff35204 | 2012-05-26 12:05:11 -0400 | [diff] [blame] | 136 | memcpy((struct bcm_leader *)skb_pull(Packet, (ETH_HLEN - LEADER_SIZE)), &Leader, LEADER_SIZE); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 137 | } |
| 138 | |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 139 | status = Adapter->interface_transmit(Adapter->pvInterfaceAdapter, |
Kevin McKinney | 22976bc | 2012-09-13 21:11:34 -0400 | [diff] [blame] | 140 | Packet->data, (Leader.PLength + LEADER_SIZE)); |
Kevin McKinney | 97e0a50 | 2012-09-13 21:11:35 -0400 | [diff] [blame] | 141 | if (status) { |
Stephen Hemminger | ac1b1ae | 2010-11-01 12:20:09 -0400 | [diff] [blame] | 142 | ++Adapter->dev->stats.tx_errors; |
| 143 | if (netif_msg_tx_err(Adapter)) |
| 144 | pr_info(PFX "%s: transmit error %d\n", Adapter->dev->name, |
| 145 | status); |
Kevin McKinney | 97e0a50 | 2012-09-13 21:11:35 -0400 | [diff] [blame] | 146 | } else { |
Andres Salomon | e6f597a | 2011-01-17 16:11:12 -0800 | [diff] [blame] | 147 | struct net_device_stats *netstats = &Adapter->dev->stats; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 148 | Adapter->PackInfo[QueueIndex].uiTotalTxBytes += Leader.PLength; |
Stephen Hemminger | cacd922 | 2010-11-01 13:34:35 -0400 | [diff] [blame] | 149 | |
Andres Salomon | e6f597a | 2011-01-17 16:11:12 -0800 | [diff] [blame] | 150 | netstats->tx_bytes += Leader.PLength; |
| 151 | ++netstats->tx_packets; |
Stephen Hemminger | cacd922 | 2010-11-01 13:34:35 -0400 | [diff] [blame] | 152 | |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 153 | Adapter->PackInfo[QueueIndex].uiCurrentTokenCount -= Leader.PLength << 3; |
| 154 | Adapter->PackInfo[QueueIndex].uiSentBytes += (Packet->len); |
| 155 | Adapter->PackInfo[QueueIndex].uiSentPackets++; |
| 156 | Adapter->PackInfo[QueueIndex].NumOfPacketsSent++; |
| 157 | |
| 158 | atomic_dec(&Adapter->PackInfo[QueueIndex].uiPerSFTxResourceCount); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 159 | Adapter->PackInfo[QueueIndex].uiThisPeriodSentBytes += Leader.PLength; |
| 160 | } |
| 161 | |
Stephen Hemminger | ac1b1ae | 2010-11-01 12:20:09 -0400 | [diff] [blame] | 162 | atomic_dec(&Adapter->CurrNumFreeTxDesc); |
| 163 | |
| 164 | errExit: |
Stephen Hemminger | 082e889 | 2010-11-01 09:35:21 -0400 | [diff] [blame] | 165 | dev_kfree_skb(Packet); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 166 | return status; |
| 167 | } |
| 168 | |
Kevin McKinney | 2979460 | 2012-05-26 12:05:12 -0400 | [diff] [blame] | 169 | static int tx_pending(struct bcm_mini_adapter *Adapter) |
Stephen Hemminger | 71e253b | 2010-11-01 09:49:30 -0400 | [diff] [blame] | 170 | { |
| 171 | return (atomic_read(&Adapter->TxPktAvail) |
| 172 | && MINIMUM_PENDING_DESCRIPTORS < atomic_read(&Adapter->CurrNumFreeTxDesc)) |
| 173 | || Adapter->device_removed || (1 == Adapter->downloadDDR); |
| 174 | } |
| 175 | |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 176 | /** |
Kevin McKinney | b9e25f8 | 2012-09-13 21:11:37 -0400 | [diff] [blame] | 177 | * @ingroup tx_functions |
| 178 | * Transmit thread |
| 179 | */ |
Kevin McKinney | 22976bc | 2012-09-13 21:11:34 -0400 | [diff] [blame] | 180 | int tx_pkt_handler(struct bcm_mini_adapter *Adapter /**< pointer to adapter object*/) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 181 | { |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 182 | int status = 0; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 183 | |
Kevin McKinney | 22976bc | 2012-09-13 21:11:34 -0400 | [diff] [blame] | 184 | while (!kthread_should_stop()) { |
Stephen Hemminger | 71e253b | 2010-11-01 09:49:30 -0400 | [diff] [blame] | 185 | /* FIXME - the timeout looks like workaround for racey usage of TxPktAvail */ |
Kevin McKinney | 22976bc | 2012-09-13 21:11:34 -0400 | [diff] [blame] | 186 | if (Adapter->LinkUpStatus) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 187 | wait_event_timeout(Adapter->tx_packet_wait_queue, |
Kevin McKinney | 22976bc | 2012-09-13 21:11:34 -0400 | [diff] [blame] | 188 | tx_pending(Adapter), msecs_to_jiffies(10)); |
Stephen Hemminger | 71e253b | 2010-11-01 09:49:30 -0400 | [diff] [blame] | 189 | else |
| 190 | wait_event_interruptible(Adapter->tx_packet_wait_queue, |
Kevin McKinney | 22976bc | 2012-09-13 21:11:34 -0400 | [diff] [blame] | 191 | tx_pending(Adapter)); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 192 | |
Stephen Hemminger | 71e253b | 2010-11-01 09:49:30 -0400 | [diff] [blame] | 193 | if (Adapter->device_removed) |
| 194 | break; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 195 | |
Kevin McKinney | 97e0a50 | 2012-09-13 21:11:35 -0400 | [diff] [blame] | 196 | if (Adapter->downloadDDR == 1) { |
Kevin McKinney | 22976bc | 2012-09-13 21:11:34 -0400 | [diff] [blame] | 197 | Adapter->downloadDDR += 1; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 198 | status = download_ddr_settings(Adapter); |
Kevin McKinney | 22976bc | 2012-09-13 21:11:34 -0400 | [diff] [blame] | 199 | if (status) |
Stephen Hemminger | ac1b1ae | 2010-11-01 12:20:09 -0400 | [diff] [blame] | 200 | pr_err(PFX "DDR DOWNLOAD FAILED! %d\n", status); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 201 | continue; |
| 202 | } |
| 203 | |
Kevin McKinney | b9e25f8 | 2012-09-13 21:11:37 -0400 | [diff] [blame] | 204 | /* Check end point for halt/stall. */ |
Kevin McKinney | 97e0a50 | 2012-09-13 21:11:35 -0400 | [diff] [blame] | 205 | if (Adapter->bEndPointHalted == TRUE) { |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 206 | Bcm_clear_halt_of_endpoints(Adapter); |
Lisa Nguyen | f70c8a9 | 2013-10-28 01:36:19 -0700 | [diff] [blame] | 207 | Adapter->bEndPointHalted = false; |
Kevin McKinney | d6861cf | 2012-11-01 23:42:21 -0400 | [diff] [blame] | 208 | StartInterruptUrb((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter)); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 209 | } |
| 210 | |
Kevin McKinney | 97e0a50 | 2012-09-13 21:11:35 -0400 | [diff] [blame] | 211 | if (Adapter->LinkUpStatus && !Adapter->IdleMode) { |
Kevin McKinney | 22976bc | 2012-09-13 21:11:34 -0400 | [diff] [blame] | 212 | if (atomic_read(&Adapter->TotalPacketCount)) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 213 | update_per_sf_desc_cnts(Adapter); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 214 | } |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 215 | |
Kevin McKinney | 22976bc | 2012-09-13 21:11:34 -0400 | [diff] [blame] | 216 | if (atomic_read(&Adapter->CurrNumFreeTxDesc) && |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 217 | Adapter->LinkStatus == SYNC_UP_REQUEST && |
Kevin McKinney | 97e0a50 | 2012-09-13 21:11:35 -0400 | [diff] [blame] | 218 | !Adapter->bSyncUpRequestSent) { |
| 219 | |
Kevin McKinney | 22976bc | 2012-09-13 21:11:34 -0400 | [diff] [blame] | 220 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Calling LinkMessage"); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 221 | LinkMessage(Adapter); |
| 222 | } |
| 223 | |
Kevin McKinney | 97e0a50 | 2012-09-13 21:11:35 -0400 | [diff] [blame] | 224 | if ((Adapter->IdleMode || Adapter->bShutStatus) && atomic_read(&Adapter->TotalPacketCount)) { |
Kevin McKinney | 22976bc | 2012-09-13 21:11:34 -0400 | [diff] [blame] | 225 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Device in Low Power mode...waking up"); |
| 226 | Adapter->usIdleModePattern = ABORT_IDLE_MODE; |
| 227 | Adapter->bWakeUpDevice = TRUE; |
| 228 | wake_up(&Adapter->process_rx_cntrlpkt); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 229 | } |
| 230 | |
Stephen Hemminger | 71e253b | 2010-11-01 09:49:30 -0400 | [diff] [blame] | 231 | transmit_packets(Adapter); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 232 | atomic_set(&Adapter->TxPktAvail, 0); |
| 233 | } |
Stephen Hemminger | 71e253b | 2010-11-01 09:49:30 -0400 | [diff] [blame] | 234 | |
Kevin McKinney | 22976bc | 2012-09-13 21:11:34 -0400 | [diff] [blame] | 235 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Exiting the tx thread..\n"); |
Stephen Hemminger | 71e253b | 2010-11-01 09:49:30 -0400 | [diff] [blame] | 236 | Adapter->transmit_packet_thread = NULL; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 237 | return 0; |
| 238 | } |