diff --git a/src/nm-device-modem.c b/src/nm-device-modem.c
index 24d9cef..2331bd7 100644
--- a/src/nm-device-modem.c
+++ b/src/nm-device-modem.c
@@ -47,6 +47,7 @@ typedef struct {
 	NMModem *modem;
 	NMDeviceModemCapabilities caps;
 	NMDeviceModemCapabilities current_caps;
+	gboolean rf_enabled;
 } NMDeviceModemPrivate;
 
 enum {
@@ -56,15 +57,6 @@ enum {
 	PROP_CURRENT_CAPABILITIES,
 };
 
-enum {
-	PROPERTIES_CHANGED,
-	ENABLE_CHANGED,
-	LAST_SIGNAL
-};
-static guint signals[LAST_SIGNAL] = { 0 };
-
-static void set_enabled (NMDevice *device, gboolean enabled);
-
 /*****************************************************************************/
 
 static void
@@ -170,12 +162,27 @@ data_port_changed_cb (NMModem *modem, GParamSpec *pspec, gpointer user_data)
 static void
 modem_enabled_cb (NMModem *modem, GParamSpec *pspec, gpointer user_data)
 {
-	NMDeviceModem *self = NM_DEVICE_MODEM (user_data);
-	NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (self);
-
-	set_enabled (NM_DEVICE (self), nm_modem_get_mm_enabled (priv->modem));
+	NMDevice *device = NM_DEVICE (user_data);
+	NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device);
+	NMDeviceState state;
 
-	g_signal_emit (G_OBJECT (self), signals[ENABLE_CHANGED], 0);
+	/* Will be called whenever the ModemManager modem enabled state is
+	 * changed, either in response to external changes (something hitting up
+	 * ModemManager directly) or internally due to rfkill/user preference changes.
+	 * However, since the rfkill handler already deals with making the device
+	 * unavailable on rfkill, we only need to deal with the case of something
+	 * disabling the device through MM directly.
+	 */
+
+	if (priv->rf_enabled && nm_modem_get_mm_enabled (modem) == FALSE) {
+		state = nm_device_get_state (device);
+		if (nm_device_is_activating (device) || state == NM_DEVICE_STATE_ACTIVATED) {
+			/* user-initiated action, hence DISCONNECTED not FAILED */
+			nm_device_state_changed (device,
+			                         NM_DEVICE_STATE_DISCONNECTED,
+			                         NM_DEVICE_STATE_REASON_USER_REQUESTED);
+		}
+	}
 }
 
 static void
@@ -315,7 +322,9 @@ act_stage3_ip6_config_start (NMDevice *device,
 static gboolean
 get_enabled (NMDevice *device)
 {
-	return nm_modem_get_mm_enabled (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem);
+	NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device);
+
+	return priv->rf_enabled && nm_modem_get_mm_enabled (priv->modem);
 }
 
 static void
@@ -323,21 +332,36 @@ set_enabled (NMDevice *device, gboolean enabled)
 {
 	NMDeviceModem *self = NM_DEVICE_MODEM (device);
 	NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (self);
-	NMDeviceState state;
+
+	/* Called only by the Manager in response to rfkill switch changes or
+	 * global user WWAN enable/disable preference changes.
+	 */
+	priv->rf_enabled = enabled;
 
 	if (priv->modem) {
+		/* Sync the ModemManager modem enabled/disabled with rfkill/user preference */
 		nm_modem_set_mm_enabled (priv->modem, enabled);
+	}
 
-		if (enabled == FALSE) {
-			state = nm_device_get_state (device);
-			if (nm_device_is_activating (device) || state == NM_DEVICE_STATE_ACTIVATED) {
-				/* user-initiated action, hence DISCONNECTED not FAILED */
-				nm_device_state_changed (device,
-				                         NM_DEVICE_STATE_DISCONNECTED,
-				                         NM_DEVICE_STATE_REASON_USER_REQUESTED);
-			}
-		}
+	if (enabled == FALSE) {
+		nm_device_state_changed (device,
+		                         NM_DEVICE_STATE_UNAVAILABLE,
+		                         NM_DEVICE_STATE_REASON_NONE);
+	}
+}
+
+static gboolean
+is_available (NMDevice *dev)
+{
+	NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (dev);
+
+	/* The device is available whenever it's not rfkilled */
+	if (!priv->rf_enabled) {
+		nm_log_dbg (LOGD_MB, "(%s): not available because WWAN airplane mode is on",
+		            nm_device_get_iface (dev));
 	}
+
+	return priv->rf_enabled;
 }
 
 /*****************************************************************************/
@@ -500,6 +524,7 @@ nm_device_modem_class_init (NMDeviceModemClass *mclass)
 	device_class->ip4_config_pre_commit = ip4_config_pre_commit;
 	device_class->get_enabled = get_enabled;
 	device_class->set_enabled = set_enabled;
+	device_class->is_available = is_available;
 
 	device_class->state_changed = device_state_changed;
 
@@ -526,19 +551,6 @@ nm_device_modem_class_init (NMDeviceModemClass *mclass)
 		                   0, G_MAXUINT32, NM_DEVICE_MODEM_CAPABILITY_NONE,
 		                   G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
-	/* Signals */
-	signals[PROPERTIES_CHANGED] =
-		nm_properties_changed_signal_new (object_class,
-		                                  G_STRUCT_OFFSET (NMDeviceModemClass, properties_changed));
-
-	signals[ENABLE_CHANGED] =
-		g_signal_new (NM_DEVICE_MODEM_ENABLE_CHANGED,
-					  G_OBJECT_CLASS_TYPE (object_class),
-					  G_SIGNAL_RUN_FIRST,
-					  0, NULL, NULL,
-					  g_cclosure_marshal_VOID__VOID,
-					  G_TYPE_NONE, 0);
-
 	dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (mclass),
-	                                 &dbus_glib_nm_device_modem_object_info);
+	                                        &dbus_glib_nm_device_modem_object_info);
 }
diff --git a/src/nm-device-modem.h b/src/nm-device-modem.h
index 85c626a..84d12f1 100644
--- a/src/nm-device-modem.h
+++ b/src/nm-device-modem.h
@@ -38,8 +38,6 @@
 #define NM_DEVICE_MODEM_CAPABILITIES "modem-capabilities"
 #define NM_DEVICE_MODEM_CURRENT_CAPABILITIES "current-capabilities"
 
-#define NM_DEVICE_MODEM_ENABLE_CHANGED "enable-changed"
-
 typedef struct {
 	NMDevice parent;
 } NMDeviceModem;
diff --git a/src/nm-manager.c b/src/nm-manager.c
index 3dc60d8..406d75c 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -165,7 +165,7 @@ static GSList * remove_one_device (NMManager *manager,
                                    NMDevice *device,
                                    gboolean quitting);
 
-static void rfkill_change_wifi (const char *desc, gboolean enabled);
+static void rfkill_change (const char *desc, RfKillType rtype, gboolean enabled);
 
 #define SSD_POKE_INTERVAL 120
 #define ORIGDEV_TAG "originating-device"
@@ -190,7 +190,6 @@ struct PendingActivation {
 
 typedef struct {
 	gboolean user_enabled;
-	gboolean daemon_enabled;
 	gboolean sw_enabled;
 	gboolean hw_enabled;
 	RfKillType rtype;
@@ -199,7 +198,6 @@ typedef struct {
 	const char *prop;
 	const char *hw_prop;
 	RfKillState (*other_enabled_func) (NMManager *);
-	RfKillState (*daemon_enabled_func) (NMManager *);
 } RadioState;
 
 typedef struct {
@@ -1470,11 +1468,8 @@ radio_enabled_for_rstate (RadioState *rstate, gboolean check_changeable)
 	gboolean enabled;
 
 	enabled = rstate->user_enabled && rstate->hw_enabled;
-	if (check_changeable) {
+	if (check_changeable)
 		enabled &= rstate->sw_enabled;
-		if (rstate->daemon_enabled_func)
-			enabled &= rstate->daemon_enabled;
-	}
 	return enabled;
 }
 
@@ -1572,29 +1567,6 @@ nm_manager_get_ipw_rfkill_state (NMManager *self)
 	return ipw_state;
 }
 
-static RfKillState
-nm_manager_get_modem_enabled_state (NMManager *self)
-{
-	NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
-	GSList *iter;
-	RfKillState wwan_state = RFKILL_UNBLOCKED;
-
-	for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
-		NMDevice *candidate = NM_DEVICE (iter->data);
-		RfKillState candidate_state = RFKILL_UNBLOCKED;
-
-		if (nm_device_get_rfkill_type (candidate) == RFKILL_TYPE_WWAN) {
-			if (!nm_device_get_enabled (candidate))
-				candidate_state = RFKILL_SOFT_BLOCKED;
-
-			if (candidate_state > wwan_state)
-				wwan_state = candidate_state;
-		}
-	}
-
-	return wwan_state;
-}
-
 static void
 update_rstate_from_rfkill (RadioState *rstate, RfKillState rfkill)
 {
@@ -1619,8 +1591,7 @@ manager_rfkill_update_one_type (NMManager *self,
 	RfKillState udev_state = RFKILL_UNBLOCKED;
 	RfKillState other_state = RFKILL_UNBLOCKED;
 	RfKillState composite;
-	gboolean old_enabled, new_enabled, old_rfkilled, new_rfkilled;
-	gboolean old_hwe, old_daemon_enabled = FALSE;
+	gboolean old_enabled, new_enabled, old_rfkilled, new_rfkilled, old_hwe;
 
 	old_enabled = radio_enabled_for_rstate (rstate, TRUE);
 	old_rfkilled = rstate->hw_enabled && rstate->sw_enabled;
@@ -1641,26 +1612,10 @@ manager_rfkill_update_one_type (NMManager *self,
 
 	update_rstate_from_rfkill (rstate, composite);
 
-	/* If the device has a management daemon that can affect enabled state, check that now */
-	if (rstate->daemon_enabled_func) {
-		old_daemon_enabled = rstate->daemon_enabled;
-		rstate->daemon_enabled = (rstate->daemon_enabled_func (self) == RFKILL_UNBLOCKED);
-		if (old_daemon_enabled != rstate->daemon_enabled) {
-			nm_log_info (LOGD_RFKILL, "%s now %s by management service",
-				         rstate->desc,
-				         rstate->daemon_enabled ? "enabled" : "disabled");
-		}
-	}
-
 	/* Print out all states affecting device enablement */
 	if (rstate->desc) {
-		if (rstate->daemon_enabled_func) {
-			nm_log_dbg (LOGD_RFKILL, "%s hw-enabled %d sw-enabled %d daemon-enabled %d",
-			            rstate->desc, rstate->hw_enabled, rstate->sw_enabled, rstate->daemon_enabled);
-		} else {
-			nm_log_dbg (LOGD_RFKILL, "%s hw-enabled %d sw-enabled %d",
-			            rstate->desc, rstate->hw_enabled, rstate->sw_enabled);
-		}
+		nm_log_dbg (LOGD_RFKILL, "%s hw-enabled %d sw-enabled %d",
+		            rstate->desc, rstate->hw_enabled, rstate->sw_enabled);
 	}
 
 	/* Log new killswitch state */
@@ -1711,12 +1666,6 @@ manager_ipw_rfkill_state_changed (NMDeviceWifi *device,
 }
 
 static void
-manager_modem_enabled_changed (NMDevice *device, gpointer user_data)
-{
-	nm_manager_rfkill_update (NM_MANAGER (user_data), RFKILL_TYPE_WWAN);
-}
-
-static void
 device_auth_done_cb (NMAuthChain *chain,
                      GError *auth_error,
                      DBusGMethodInvocation *context,
@@ -1866,10 +1815,6 @@ add_device (NMManager *self, NMDevice *device)
 		g_signal_connect (device, "notify::" NM_DEVICE_WIFI_IPW_RFKILL_STATE,
 		                  G_CALLBACK (manager_ipw_rfkill_state_changed),
 		                  self);
-	} else if (devtype == NM_DEVICE_TYPE_MODEM) {
-		g_signal_connect (device, NM_DEVICE_MODEM_ENABLE_CHANGED,
-		                  G_CALLBACK (manager_modem_enabled_changed),
-		                  self);
 	}
 
 	/* Update global rfkill state for this device type with the device's
@@ -4158,11 +4103,13 @@ nm_manager_new (NMSettings *settings,
 	                  G_CALLBACK (bluez_manager_bdaddr_removed_cb),
 	                  singleton);
 
-	/* Force kernel WiFi rfkill state to follow NM saved wifi state in case
-	 * the BIOS doesn't save rfkill state, and to be consistent with user
-	 * changes to the WirelessEnabled property which toggles kernel rfkill.
+	/* Force kernel WiFi/WWAN rfkill state to follow NM saved WiFi/WWAN state
+	 * in case the BIOS doesn't save rfkill state, and to be consistent with user
+	 * changes to the WirelessEnabled/WWANEnabled properties which toggle kernel
+	 * rfkill.
 	 */
-	rfkill_change_wifi (priv->radio_states[RFKILL_TYPE_WLAN].desc, initial_wifi_enabled);
+	rfkill_change (priv->radio_states[RFKILL_TYPE_WLAN].desc, RFKILL_TYPE_WLAN, initial_wifi_enabled);
+	rfkill_change (priv->radio_states[RFKILL_TYPE_WWAN].desc, RFKILL_TYPE_WWAN, initial_wwan_enabled);
 
 	return singleton;
 }
@@ -4279,6 +4226,7 @@ dispose (GObject *object)
 
 #define KERN_RFKILL_OP_CHANGE_ALL 3
 #define KERN_RFKILL_TYPE_WLAN     1
+#define KERN_RFKILL_TYPE_WWAN     5
 struct rfkill_event {
 	__u32 idx;
 	__u8  type;
@@ -4287,12 +4235,14 @@ struct rfkill_event {
 } __attribute__((packed));
 
 static void
-rfkill_change_wifi (const char *desc, gboolean enabled)
+rfkill_change (const char *desc, RfKillType rtype, gboolean enabled)
 {
 	int fd;
 	struct rfkill_event event;
 	ssize_t len;
 
+	g_return_if_fail (rtype == RFKILL_TYPE_WLAN || rtype == RFKILL_TYPE_WWAN);
+
 	errno = 0;
 	fd = open ("/dev/rfkill", O_RDWR);
 	if (fd < 0) {
@@ -4311,7 +4261,16 @@ rfkill_change_wifi (const char *desc, gboolean enabled)
 
 	memset (&event, 0, sizeof (event));
 	event.op = KERN_RFKILL_OP_CHANGE_ALL;
-	event.type = KERN_RFKILL_TYPE_WLAN;
+	switch (rtype) {
+	case RFKILL_TYPE_WLAN:
+		event.type = KERN_RFKILL_TYPE_WLAN;
+		break;
+	case RFKILL_TYPE_WWAN:
+		event.type = KERN_RFKILL_TYPE_WWAN;
+		break;
+	default:
+		g_assert_not_reached ();
+	}
 	event.soft = enabled ? 0 : 1;
 
 	len = write (fd, &event, sizeof (event));
@@ -4338,6 +4297,10 @@ manager_radio_user_toggled (NMManager *self,
 	GError *error = NULL;
 	gboolean old_enabled, new_enabled;
 
+	/* Don't touch devices if asleep/networking disabled */
+	if (manager_sleeping (self))
+		return;
+
 	if (rstate->desc) {
 		nm_log_dbg (LOGD_RFKILL, "(%s): setting radio %s by user",
 		            rstate->desc,
@@ -4371,11 +4334,11 @@ manager_radio_user_toggled (NMManager *self,
 	rstate->user_enabled = enabled;
 	new_enabled = radio_enabled_for_rstate (rstate, FALSE);
 	if (new_enabled != old_enabled) {
-		manager_update_radio_enabled (self, rstate, new_enabled);
+		/* Try to change the kernel rfkill state */
+		if (rstate->rtype == RFKILL_TYPE_WLAN || rstate->rtype == RFKILL_TYPE_WWAN)
+			rfkill_change (rstate->desc, rstate->rtype, new_enabled);
 
-		/* For WiFi only (for now) set the actual kernel rfkill state */
-		if (rstate->rtype == RFKILL_TYPE_WLAN)
-			rfkill_change_wifi (rstate->desc, new_enabled);
+		manager_update_radio_enabled (self, rstate, new_enabled);
 	}
 }
 
@@ -4515,7 +4478,6 @@ nm_manager_init (NMManager *manager)
 	priv->radio_states[RFKILL_TYPE_WWAN].prop = NM_MANAGER_WWAN_ENABLED;
 	priv->radio_states[RFKILL_TYPE_WWAN].hw_prop = NM_MANAGER_WWAN_HARDWARE_ENABLED;
 	priv->radio_states[RFKILL_TYPE_WWAN].desc = "WWAN";
-	priv->radio_states[RFKILL_TYPE_WWAN].daemon_enabled_func = nm_manager_get_modem_enabled_state;
 	priv->radio_states[RFKILL_TYPE_WWAN].rtype = RFKILL_TYPE_WWAN;
 
 	priv->radio_states[RFKILL_TYPE_WIMAX].user_enabled = TRUE;
diff --git a/src/nm-policy.c b/src/nm-policy.c
index 38a0361..90499f8 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -1478,12 +1478,6 @@ nsps_changed (NMDevice *device, GObject *nsp, gpointer user_data)
 	schedule_activate_check ((NMPolicy *) user_data, device, 0);
 }
 
-static void
-modem_enabled_changed (NMDevice *device, gpointer user_data)
-{
-	schedule_activate_check ((NMPolicy *) (user_data), device, 0);
-}
-
 typedef struct {
 	gulong id;
 	NMDevice *device;
@@ -1520,9 +1514,6 @@ device_added (NMManager *manager, NMDevice *device, gpointer user_data)
 		_connect_device_signal (policy, device, "nsp-added", nsps_changed);
 		_connect_device_signal (policy, device, "nsp-removed", nsps_changed);
 		break;
-	case NM_DEVICE_TYPE_MODEM:
-		_connect_device_signal (policy, device, "enable-changed", modem_enabled_changed);
-		break;
 	default:
 		break;
 	}
