Index: uspace/app/nic/nic.c
===================================================================
--- uspace/app/nic/nic.c	(revision 7493e7b128b8fc8029d87ee738eedfbec825e676)
+++ uspace/app/nic/nic.c	(revision 96e368a61482194923fef78ac804b0906e9668b9)
@@ -55,5 +55,50 @@
 {
 	printf("syntax:\n");
-	printf("\t" NAME "\n");
+	printf("\t" NAME " [<index> <cmd> [<args...>]]\n");
+	printf("\t<index> is NIC index number reported by the tool\n");
+	printf("\t<cmd> is:\n");
+	printf("\taddr <mac_address> - set MAC address\n");
+	printf("\tspeed <10|100|1000> - set NIC speed\n");
+	printf("\tduplex <half|full> - set duplex mode\n");
+}
+
+static async_sess_t *get_nic_by_index(size_t i)
+{
+	int rc;
+	size_t count;
+	char *svc_name;
+	category_id_t nic_cat;
+	service_id_t *nics = NULL;
+	async_sess_t *sess;
+
+	rc = loc_category_get_id("nic", &nic_cat, 0);
+	if (rc != EOK) {
+		printf("Error resolving category 'nic'.\n");
+		goto error;
+	}
+
+	rc = loc_category_get_svcs(nic_cat, &nics, &count);
+	if (rc != EOK) {
+		printf("Error getting list of NICs.\n");
+		goto error;
+	}
+
+	rc = loc_service_get_name(nics[i], &svc_name);
+	if (rc != EOK) {
+		printf("Error getting service name.\n");
+		goto error;
+	}
+
+	printf("Using device: %s\n", svc_name);
+
+	sess = loc_service_connect(EXCHANGE_SERIALIZE, nics[i], 0);
+	if (sess == NULL) {
+		printf("Error connecting to service.\n");
+		goto error;
+	}
+
+	return sess;
+error:
+	return NULL;
 }
 
@@ -67,6 +112,5 @@
 	sess = loc_service_connect(EXCHANGE_SERIALIZE, svc_id, 0);
 	if (sess == NULL) {
-		printf("Error connecting '%s'.\n", svc_name);
-		rc = EIO;
+		printf("Error connecting to service.\n");
 		goto error;
 	}
@@ -121,4 +165,5 @@
 	case NIC_CM_FULL_DUPLEX: return "full-duplex";
 	case NIC_CM_HALF_DUPLEX: return "half-duplex";
+	case NIC_CM_SIMPLEX: return "simplex";
 	default: assert(false); return NULL;
 	}
@@ -161,5 +206,5 @@
 	}
 
-	printf("[Address] [Service Name]\n");
+	printf("[Service Name]\n");
 	for (i = 0; i < count; i++) {
 		rc = loc_service_get_name(nics[i], &svc_name);
@@ -180,5 +225,6 @@
 		}
 
-		printf("%s %s\n", addr_str, svc_name);
+		printf("%d: %s\n", i, svc_name);
+		printf("\tMAC address: %s\n", addr_str);
 		printf("\tVendor name: %s\n",
 		    nic_info.device_info.vendor_name);
@@ -203,7 +249,109 @@
 }
 
+static int nic_set_speed(int i, char *str)
+{
+	async_sess_t *sess;
+	uint32_t speed;
+	int oldspeed;
+	nic_channel_mode_t oldduplex;
+	nic_role_t oldrole;
+	int rc;
+
+	rc = str_uint32_t(str, NULL, 10, false, &speed);
+	if (rc != EOK) {
+		printf("Speed must be a numeric value.\n");
+		return rc;
+	}
+
+	if (speed != 10 && speed != 100 && speed != 1000) {
+		printf("Speed must be one of: 10, 100, 1000.\n");
+		return EINVAL;
+	}
+
+	sess = get_nic_by_index(i);
+	if (sess == NULL) {
+		printf("Specified NIC doesn't exist or cannot connect to it.\n");
+		return EINVAL;
+	}
+
+	rc = nic_get_operation_mode(sess, &oldspeed, &oldduplex, &oldrole);
+	if (rc != EOK) {
+		printf("Error getting NIC speed and duplex mode.\n");
+		return EIO;
+	}
+
+	return nic_set_operation_mode(sess, speed, oldduplex, oldrole);
+}
+
+static int nic_set_duplex(int i, char *str)
+{
+	async_sess_t *sess;
+	int oldspeed;
+	nic_channel_mode_t duplex = NIC_CM_UNKNOWN;
+	nic_channel_mode_t oldduplex;
+	nic_role_t oldrole;
+	int rc;
+
+	if (!str_cmp(str, "half"))
+		duplex = NIC_CM_HALF_DUPLEX;
+
+	if (!str_cmp(str, "full"))
+		duplex = NIC_CM_FULL_DUPLEX;
+
+	if (!str_cmp(str, "simplex"))
+		duplex = NIC_CM_SIMPLEX;
+
+	if (duplex == NIC_CM_UNKNOWN) {
+		printf("Invalid duplex specification.\n");
+		return EINVAL;
+	}
+
+	sess = get_nic_by_index(i);
+	if (sess == NULL) {
+		printf("Specified NIC doesn't exist or cannot connect to it.\n");
+		return EINVAL;
+	}
+
+	rc = nic_get_operation_mode(sess, &oldspeed, &oldduplex, &oldrole);
+	if (rc != EOK) {
+		printf("Error getting NIC speed and duplex mode.\n");
+		return EIO;
+	}
+
+	return nic_set_operation_mode(sess, oldspeed, duplex, oldrole);
+}
+
+static int nic_set_addr(int i, char *str)
+{
+	async_sess_t *sess;
+	nic_address_t addr;
+	int rc, idx;
+
+	sess = get_nic_by_index(i);
+	if (sess == NULL) {
+		printf("Specified NIC doesn't exist or cannot connect to it.\n");
+		return EINVAL;
+	}
+
+	if (str_size(str) != 17) {
+		printf("Invalid MAC address specified");
+		return EINVAL;
+	}
+
+	for (idx = 0; idx < 6; idx++) {
+		rc = str_uint8_t(&str[idx * 3], NULL, 16, false, &addr.address[idx]);
+		if (rc != EOK) {
+			printf("Invalid MAC address specified");
+			return EINVAL;
+		}
+	}
+
+	return nic_set_address(sess, &addr);
+}
+
 int main(int argc, char *argv[])
 {
 	int rc;
+	uint32_t index;
 
 	if (argc == 1) {
@@ -211,4 +359,21 @@
 		if (rc != EOK)
 			return 1;
+	} else if (argc >= 3) {
+		rc = str_uint32_t(argv[1], NULL, 10, false, &index);
+		if (rc != EOK) {
+			printf(NAME ": Invalid argument.\n");
+			print_syntax();
+			return 1;
+		}
+
+		if (!str_cmp(argv[2], "addr"))
+			return nic_set_addr(index, argv[3]);
+
+		if (!str_cmp(argv[2], "speed"))
+			return nic_set_speed(index, argv[3]);
+
+		if (!str_cmp(argv[2], "duplex"))
+			return nic_set_duplex(index, argv[3]);
+
 	} else {
 		printf(NAME ": Invalid argument.\n");
