static int gelic_card_set_link_mode(struct gelic_card *card, int mode)
{
	int status;
	u64 v1, v2;

	status = lv1_net_control(bus_id(card), dev_id(card),
				 GELIC_LV1_SET_NEGOTIATION_MODE,
				 GELIC_LV1_PHY_ETHERNET_0, mode, 0, &v1, &v2);
	if (status) {
		pr_info("%s: failed setting negotiation mode %d\n", __func__,
			status);
		return -EBUSY;
	}

	card->link_mode = mode;
	return 0;
}
static void gelic_card_get_ether_port_status(struct gelic_card *card,
					     int inform)
{
	u64 v2;
	struct net_device *ether_netdev;

	lv1_net_control(bus_id(card), dev_id(card),
			GELIC_LV1_GET_ETH_PORT_STATUS,
			GELIC_LV1_VLAN_TX_ETHERNET_0, 0, 0,
			&card->ether_port_status, &v2);

	if (inform) {
		ether_netdev = card->netdev[GELIC_PORT_ETHERNET_0];
		if (card->ether_port_status & GELIC_LV1_ETHER_LINK_UP)
			netif_carrier_on(ether_netdev);
		else
			netif_carrier_off(ether_netdev);
	}
}
Beispiel #3
0
static u32 gelic_net_get_link(struct net_device *netdev)
{
	struct gelic_net_card *card = netdev_priv(netdev);
	int status;
	u64 v1, v2;
	int link;

	status = lv1_net_control(bus_id(card), dev_id(card),
			GELIC_NET_GET_ETH_PORT_STATUS, GELIC_NET_PORT, 0, 0,
			&v1, &v2);
	if (status)
		return 0; /* link down */

	if (v1 & GELIC_NET_LINK_UP)
		link = 1;
	else
		link = 0;

	return link;
}
Beispiel #4
0
static int gelic_net_get_settings(struct net_device *netdev,
				  struct ethtool_cmd *cmd)
{
	struct gelic_net_card *card = netdev_priv(netdev);
	int status;
	u64 v1, v2;
	int speed, duplex;

	speed = duplex = -1;
	status = lv1_net_control(bus_id(card), dev_id(card),
			GELIC_NET_GET_ETH_PORT_STATUS, GELIC_NET_PORT, 0, 0,
			&v1, &v2);
	if (status) {
		/* link down */
	} else {
		if (v1 & GELIC_NET_FULL_DUPLEX) {
			duplex = DUPLEX_FULL;
		} else {
			duplex = DUPLEX_HALF;
		}

		if (v1 & GELIC_NET_SPEED_10 ) {
			speed = SPEED_10;
		} else if (v1 & GELIC_NET_SPEED_100) {
			speed = SPEED_100;
		} else if (v1 & GELIC_NET_SPEED_1000) {
			speed = SPEED_1000;
		}
	}
	cmd->supported = SUPPORTED_TP | SUPPORTED_Autoneg |
			SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
			SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
			SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full;
	cmd->advertising = cmd->supported;
	cmd->speed = speed;
	cmd->duplex = duplex;
	cmd->autoneg = AUTONEG_ENABLE; /* always enabled */
	cmd->port = PORT_TP;

	return 0;
}
/**
 * gelic_ether_setup_netdev - initialization of net_device
 * @netdev: net_device structure
 * @card: card structure
 *
 * Returns 0 on success or <0 on failure
 *
 * gelic_ether_setup_netdev initializes the net_device structure
 * and register it.
 **/
int __devinit gelic_net_setup_netdev(struct net_device *netdev,
				     struct gelic_card *card)
{
	int status;
	u64 v1, v2;

	netdev->features = NETIF_F_IP_CSUM;

	status = lv1_net_control(bus_id(card), dev_id(card),
				 GELIC_LV1_GET_MAC_ADDRESS,
				 0, 0, 0, &v1, &v2);
	v1 <<= 16;
	if (status || !is_valid_ether_addr((u8 *)&v1)) {
		dev_info(ctodev(card),
			 "%s:lv1_net_control GET_MAC_ADDR failed %d\n",
			 __func__, status);
		return -EINVAL;
	}
	memcpy(netdev->dev_addr, &v1, ETH_ALEN);

	if (card->vlan_required) {
		netdev->hard_header_len += VLAN_HLEN;
		/*
		 * As vlan is internally used,
		 * we can not receive vlan packets
		 */
		netdev->features |= NETIF_F_VLAN_CHALLENGED;
	}

	status = register_netdev(netdev);
	if (status) {
		dev_err(ctodev(card), "%s:Couldn't register %s %d\n",
			__func__, netdev->name, status);
		return status;
	}
	dev_info(ctodev(card), "%s: MAC addr %pM\n",
		 netdev->name, netdev->dev_addr);

	return 0;
}
static int gelic_net_set_wol(struct net_device *netdev,
			     struct ethtool_wolinfo *wol)
{
	int status;
	struct gelic_card *card;
	u64 v1, v2;

	if (ps3_compare_firmware_version(2, 2, 0) < 0 ||
	    !capable(CAP_NET_ADMIN))
		return -EPERM;

	if (wol->wolopts & ~WAKE_MAGIC)
		return -EINVAL;

	card = netdev_card(netdev);
	if (wol->wolopts & WAKE_MAGIC) {
		status = lv1_net_control(bus_id(card), dev_id(card),
					 GELIC_LV1_SET_WOL,
					 GELIC_LV1_WOL_MAGIC_PACKET,
					 0, GELIC_LV1_WOL_MP_ENABLE,
					 &v1, &v2);
		if (status) {
			pr_info("%s: enabling WOL failed %d\n", __func__,
				status);
			status = -EIO;
			goto done;
		}
		status = lv1_net_control(bus_id(card), dev_id(card),
					 GELIC_LV1_SET_WOL,
					 GELIC_LV1_WOL_ADD_MATCH_ADDR,
					 0, GELIC_LV1_WOL_MATCH_ALL,
					 &v1, &v2);
		if (!status)
			ps3_sys_manager_set_wol(1);
		else {
			pr_info("%s: enabling WOL filter failed %d\n",
				__func__, status);
			status = -EIO;
		}
	} else {
		status = lv1_net_control(bus_id(card), dev_id(card),
					 GELIC_LV1_SET_WOL,
					 GELIC_LV1_WOL_MAGIC_PACKET,
					 0, GELIC_LV1_WOL_MP_DISABLE,
					 &v1, &v2);
		if (status) {
			pr_info("%s: disabling WOL failed %d\n", __func__,
				status);
			status = -EIO;
			goto done;
		}
		status = lv1_net_control(bus_id(card), dev_id(card),
					 GELIC_LV1_SET_WOL,
					 GELIC_LV1_WOL_DELETE_MATCH_ADDR,
					 0, GELIC_LV1_WOL_MATCH_ALL,
					 &v1, &v2);
		if (!status)
			ps3_sys_manager_set_wol(0);
		else {
			pr_info("%s: removing WOL filter failed %d\n",
				__func__, status);
			status = -EIO;
		}
	}
done:
	return status;
}
static void gelic_debug_init(void)
{
	s64 result;
	u64 v2;
	u64 mac;
	u64 vlan_id;

	result = lv1_open_device(GELIC_BUS_ID, GELIC_DEVICE_ID, 0);
	if (result)
		lv1_panic(0);

	map_dma_mem(GELIC_BUS_ID, GELIC_DEVICE_ID, &dbg, sizeof(dbg),
		    &bus_addr);

	memset(&dbg, 0, sizeof(dbg));

	dbg.descr.buf_addr = bus_addr + offsetof(struct debug_block, pkt);

	wmb();

	result = lv1_net_control(GELIC_BUS_ID, GELIC_DEVICE_ID,
				 GELIC_LV1_GET_MAC_ADDRESS, 0, 0, 0,
				 &mac, &v2);
	if (result)
		lv1_panic(0);

	mac <<= 16;

	h_eth = (struct ethhdr *)dbg.pkt;

	memset(&h_eth->dest, 0xff, 6);
	memcpy(&h_eth->src, &mac, 6);

	header_size = sizeof(struct ethhdr);

	result = lv1_net_control(GELIC_BUS_ID, GELIC_DEVICE_ID,
				 GELIC_LV1_GET_VLAN_ID,
				 GELIC_LV1_VLAN_TX_ETHERNET_0, 0, 0,
				 &vlan_id, &v2);
	if (!result) {
		h_eth->type = 0x8100;

		header_size += sizeof(struct vlantag);
		h_vlan = (struct vlantag *)(h_eth + 1);
		h_vlan->vlan = vlan_id;
		h_vlan->subtype = 0x0800;
		h_ip = (struct iphdr *)(h_vlan + 1);
	} else {
		h_eth->type = 0x0800;
		h_ip = (struct iphdr *)(h_eth + 1);
	}

	header_size += sizeof(struct iphdr);
	h_ip->ver_len = 0x45;
	h_ip->ttl = 10;
	h_ip->proto = 0x11;
	h_ip->src = 0x00000000;
	h_ip->dest = 0xffffffff;

	header_size += sizeof(struct udphdr);
	h_udp = (struct udphdr *)(h_ip + 1);
	h_udp->src = GELIC_DEBUG_PORT;
	h_udp->dest = GELIC_DEBUG_PORT;

	pmsgc = pmsg = (char *)(h_udp + 1);
}
Beispiel #8
0
/**
 * gelic_net_setup_netdev - initialization of net_device
 * @card: card structure
 *
 * Returns 0 on success or <0 on failure
 *
 * gelic_net_setup_netdev initializes the net_device structure
 **/
static int gelic_net_setup_netdev(struct gelic_net_card *card)
{
	struct net_device *netdev = card->netdev;
	struct sockaddr addr;
	unsigned int i;
	int status;
	u64 v1, v2;

	SET_MODULE_OWNER(netdev);
	SET_NETDEV_DEV(netdev, &card->dev->core);
	spin_lock_init(&card->tx_dma_lock);

	card->rx_csum = GELIC_NET_RX_CSUM_DEFAULT;

	gelic_net_setup_netdev_ops(netdev);

	netdev->features = NETIF_F_IP_CSUM;

	status = lv1_net_control(bus_id(card), dev_id(card),
				 GELIC_NET_GET_MAC_ADDRESS,
				 0, 0, 0, &v1, &v2);
	if (status || !is_valid_ether_addr((u8 *)&v1)) {
		dev_info(ctodev(card),
			 "%s:lv1_net_control GET_MAC_ADDR failed %d\n",
			 __func__, status);
		return -EINVAL;
	}
	v1 <<= 16;
	memcpy(addr.sa_data, &v1, ETH_ALEN);
	memcpy(netdev->dev_addr, addr.sa_data, ETH_ALEN);
	dev_info(ctodev(card), "MAC addr %02x:%02x:%02x:%02x:%02x:%02x\n",
		 netdev->dev_addr[0], netdev->dev_addr[1],
		 netdev->dev_addr[2], netdev->dev_addr[3],
		 netdev->dev_addr[4], netdev->dev_addr[5]);

	card->vlan_index = -1;	/* no vlan */
	for (i = 0; i < GELIC_NET_VLAN_MAX; i++) {
		status = lv1_net_control(bus_id(card), dev_id(card),
					GELIC_NET_GET_VLAN_ID,
					i + 1, /* index; one based */
					0, 0, &v1, &v2);
		if (status == GELIC_NET_VLAN_NO_ENTRY) {
			dev_dbg(ctodev(card),
				"GELIC_VLAN_ID no entry:%d, VLAN disabled\n",
				status);
			card->vlan_id[i] = 0;
		} else if (status) {
			dev_dbg(ctodev(card),
				"%s:GELIC_NET_VLAN_ID faild, status=%d\n",
				__func__, status);
			card->vlan_id[i] = 0;
		} else {
			card->vlan_id[i] = (u32)v1;
			dev_dbg(ctodev(card), "vlan_id:%d, %lx\n", i, v1);
		}
	}
	if (card->vlan_id[GELIC_NET_VLAN_WIRED - 1])
		card->vlan_index = GELIC_NET_VLAN_WIRED - 1;

	status = register_netdev(netdev);
	if (status) {
		dev_err(ctodev(card), "%s:Couldn't register net_device: %d\n",
			__func__, status);
		return status;
	}

	return 0;
}
Beispiel #9
0
s64 debug_init(void)
{
	s64 result;
	u64 v2;

	result = find_device_by_type(DEV_TYPE_ETH, 0, &bus_id, &dev_id, NULL);
	if (result)
		return result;

	result = map_dma_mem(bus_id, dev_id, dbg, sizeof(struct debug_block), &bus_addr);
	if (result)
		return result;

	memset(dbg, 0, sizeof(struct debug_block));

	dbg->descr.buf_addr = bus_addr + offsetof(struct debug_block, pkt);

	u64 mac;
	result = lv1_net_control(bus_id, dev_id, GELIC_LV1_GET_MAC_ADDRESS, 0, 0, 0, &mac, &v2);
	if (result)
		return result;
	mac <<= 16;

	h_eth = (struct ethhdr*)dbg->pkt;
	
	memset(&h_eth->dest, 0xff, 6);
	memcpy(&h_eth->src, &mac, 6);

	header_size = sizeof(struct ethhdr);

	u64 vlan_id;
	result = lv1_net_control(bus_id, dev_id, GELIC_LV1_GET_VLAN_ID, \
							 GELIC_LV1_VLAN_TX_ETHERNET_0, 0, 0, &vlan_id, &v2);
	if (result == 0) {
		h_eth->type = 0x8100;

		header_size += sizeof(struct vlantag);
		h_vlan = (struct vlantag*)(h_eth+1);
		h_vlan->vlan = vlan_id;
		h_vlan->subtype = 0x0800;
		h_ip = (struct iphdr*)(h_vlan+1);
	} else {
		h_eth->type = 0x0800;
		h_ip = (struct iphdr*)(h_eth+1);
	}

	header_size += sizeof(struct iphdr);
	h_ip->ver_len = 0x45;
	h_ip->ttl = 10;
	h_ip->proto = 0x11;
	h_ip->src = 0x00000000;
	h_ip->dest = 0xffffffff;

	header_size += sizeof(struct udphdr);
	h_udp = (struct udphdr*)(h_ip+1);
	h_udp->src = DEBUG_PORT;
	h_udp->dest = DEBUG_PORT;

	pmsg = (char*)(h_udp+1);

	debug_initialized = 1;

	return 0;
}