It only stays in monitor or promiscuous mode when a running process is holding it in that mode.
While this holds true most of the time when we run (on El Capitan):
# sudo tcpdump -p -I -i enX -y IEEE802_11
The interface may get stuck on monitor mode after tcpdump exits (where X
is a wireless network card that supports monitor mode).
Note that I say "may". It is not a mistake. A few times it returned to normal mode. Most of the times it did not.
Running this command afterwards fixed it (which is my answer to your question):
# sudo tcpdump -I -i enX -p
This led us to believe that there is something wrong with tcpdump or Mac OS X and the way they interface with each other (the problem could also be on libpcap which sits in between).
We proceeded to read the source code of libpcap and found multiple precious gems on the joy of monitor mode on Mac OS X which, in turn, pointed us to the fact that selecting a particular DLT mode (using the -y flag on tcpdump) would cause Mac OS X to put the interface in monitor mode (without additional work of libpcap). Also, contrary to other systems, no special cleanup of monitor mode state seems to occur on libpcap when it runs on Mac OS X.
In our case it is imperative that we are able to get 802.11 management frames (probe requests) while maintaining base station association and connectivity.
We ended up building a program that interfaced directly with libpcap and simply requested for monitor mode pcap_set_rfmon(pcap, 1)
(without selecting a DLT mode) before activating the capture on the interface.
Upon exit the program simply closes the capture handle and everything returns to normal (eye of Sauron disappears) and network card is still associated with the network. Internet access is working throughout execution.