Exemplo n.º 1
0
/* I2C receiving of bytes - does not send an offset byte */
int efx_i2c_recv_bytes(struct efx_i2c_interface *i2c, u8 device_id,
		       u8 *bytes, unsigned int len)
{
	int i;
	int rc;

	EFX_WARN_ON_PARANOID(getsda(i2c) != 1);
	EFX_WARN_ON_PARANOID(getscl(i2c) != 1);
	EFX_WARN_ON_PARANOID(len < 1);

	/* Select device */
	i2c_start(i2c);

	/* Read data from device */
	rc = i2c_send_byte(i2c, i2c_read_cmd(device_id));
	if (rc)
		goto out;

	for (i = 0; i < (len - 1); i++)
		/* Read and acknowledge all but the last byte */
		bytes[i] = i2c_recv_byte(i2c, 1);
	/* Read last byte with no acknowledgement */
	bytes[i] = i2c_recv_byte(i2c, 0);

 out:
	i2c_stop(i2c);
	i2c_release(i2c);

	return rc;
}
Exemplo n.º 2
0
/* This performs a fast write of one or more consecutive bytes to an
 * I2C device.  Not all devices support consecutive writes of more
 * than one byte; for these devices use efx_i2c_write() instead.
 */
int efx_i2c_fast_write(struct efx_i2c_interface *i2c,
		       u8 device_id, u8 offset,
		       const u8 *data, unsigned int len)
{
	int i;
	int rc;

	EFX_WARN_ON_PARANOID(getsda(i2c) != 1);
	EFX_WARN_ON_PARANOID(getscl(i2c) != 1);
	EFX_WARN_ON_PARANOID(len < 1);

	/* Select device and starting offset */
	i2c_start(i2c);
	rc = i2c_send_byte(i2c, i2c_write_cmd(device_id));
	if (rc)
		goto out;
	rc = i2c_send_byte(i2c, offset);
	if (rc)
		goto out;

	/* Write data to device */
	for (i = 0; i < len; i++) {
		rc = i2c_send_byte(i2c, data[i]);
		if (rc)
			goto out;
	}

 out:
	i2c_stop(i2c);
	i2c_release(i2c);

	return rc;
}
Exemplo n.º 3
0
static inline void i2c_release(struct efx_i2c_interface *i2c)
{
	EFX_WARN_ON_PARANOID(!i2c->scl);
	EFX_WARN_ON_PARANOID(!i2c->sda);
	/* Devices may time out if operations do not end */
	setscl(i2c, 1);
	setsda(i2c, 1);
	EFX_BUG_ON_PARANOID(getsda(i2c) != 1);
	EFX_BUG_ON_PARANOID(getscl(i2c) != 1);
}
Exemplo n.º 4
0
static inline int i2c_recv_bit(struct efx_i2c_interface *i2c)
{
	int bit;

	EFX_WARN_ON_PARANOID(i2c->scl != 0);
	EFX_WARN_ON_PARANOID(!i2c->sda);
	setscl(i2c, 1);
	bit = getsda(i2c);
	setscl(i2c, 0);
	return bit;
}
Exemplo n.º 5
0
static int efx_enqueue_skb_copy(struct efx_tx_queue *tx_queue,
				struct sk_buff *skb)
{
	unsigned int copy_len = skb->len;
	struct efx_tx_buffer *buffer;
	u8 *copy_buffer;
	int rc;

	EFX_WARN_ON_ONCE_PARANOID(copy_len > EFX_TX_CB_SIZE);

	buffer = efx_tx_queue_get_insert_buffer(tx_queue);

	copy_buffer = efx_tx_get_copy_buffer(tx_queue, buffer);
	if (unlikely(!copy_buffer))
		return -ENOMEM;

	rc = skb_copy_bits(skb, 0, copy_buffer, copy_len);
	EFX_WARN_ON_PARANOID(rc);
	buffer->len = copy_len;

	buffer->skb = skb;
	buffer->flags = EFX_TX_BUF_SKB;

	++tx_queue->insert_count;
	return rc;
}
Exemplo n.º 6
0
static inline void i2c_stop(struct efx_i2c_interface *i2c)
{
	EFX_WARN_ON_PARANOID(i2c->scl != 0);
	setsda(i2c, 0);
	setscl(i2c, 1);
	setsda(i2c, 1);
}
Exemplo n.º 7
0
static inline void i2c_send_bit(struct efx_i2c_interface *i2c, int bit)
{
	EFX_WARN_ON_PARANOID(i2c->scl != 0);
	setsda(i2c, bit);
	setscl(i2c, 1);
	setscl(i2c, 0);
	setsda(i2c, 1);
}
Exemplo n.º 8
0
static inline void i2c_start(struct efx_i2c_interface *i2c)
{
	/* We may be restarting immediately after a {send,recv}_bit,
	 * so SCL will not necessarily already be high.
	 */
	EFX_WARN_ON_PARANOID(!i2c->sda);
	setscl(i2c, 1);
	setsda(i2c, 0);
	setscl(i2c, 0);
	setsda(i2c, 1);
}
Exemplo n.º 9
0
Arquivo: tx.c Projeto: avagin/linux
static void efx_dequeue_buffer(struct efx_tx_queue *tx_queue,
			       struct efx_tx_buffer *buffer,
			       unsigned int *pkts_compl,
			       unsigned int *bytes_compl)
{
	if (buffer->unmap_len) {
		struct device *dma_dev = &tx_queue->efx->pci_dev->dev;
		dma_addr_t unmap_addr = buffer->dma_addr - buffer->dma_offset;
		if (buffer->flags & EFX_TX_BUF_MAP_SINGLE)
			dma_unmap_single(dma_dev, unmap_addr, buffer->unmap_len,
					 DMA_TO_DEVICE);
		else
			dma_unmap_page(dma_dev, unmap_addr, buffer->unmap_len,
				       DMA_TO_DEVICE);
		buffer->unmap_len = 0;
	}

	if (buffer->flags & EFX_TX_BUF_SKB) {
		struct sk_buff *skb = (struct sk_buff *)buffer->skb;

		EFX_WARN_ON_PARANOID(!pkts_compl || !bytes_compl);
		(*pkts_compl)++;
		(*bytes_compl) += skb->len;
		if (tx_queue->timestamping &&
		    (tx_queue->completed_timestamp_major ||
		     tx_queue->completed_timestamp_minor)) {
			struct skb_shared_hwtstamps hwtstamp;

			hwtstamp.hwtstamp =
				efx_ptp_nic_to_kernel_time(tx_queue);
			skb_tstamp_tx(skb, &hwtstamp);

			tx_queue->completed_timestamp_major = 0;
			tx_queue->completed_timestamp_minor = 0;
		}
		dev_consume_skb_any((struct sk_buff *)buffer->skb);
		netif_vdbg(tx_queue->efx, tx_done, tx_queue->efx->net_dev,
			   "TX queue %d transmission id %x complete\n",
			   tx_queue->queue, tx_queue->read_count);
	}

	buffer->len = 0;
	buffer->flags = 0;
}
Exemplo n.º 10
0
/* Initiate a packet transmission.  We use one channel per CPU
 * (sharing when we have more CPUs than channels).  On Falcon, the TX
 * completion events will be directed back to the CPU that transmitted
 * the packet, which should be cache-efficient.
 *
 * Context: non-blocking.
 * Note that returning anything other than NETDEV_TX_OK will cause the
 * OS to free the skb.
 */
netdev_tx_t efx_hard_start_xmit(struct sk_buff *skb,
				struct net_device *net_dev)
{
	struct efx_nic *efx = netdev_priv(net_dev);
	struct efx_tx_queue *tx_queue;
	unsigned index, type;

	EFX_WARN_ON_PARANOID(!netif_device_present(net_dev));

	index = skb_get_queue_mapping(skb);
	type = skb->ip_summed == CHECKSUM_PARTIAL ? EFX_TXQ_TYPE_OFFLOAD : 0;
	if (index >= efx->n_tx_channels) {
		index -= efx->n_tx_channels;
		type |= EFX_TXQ_TYPE_HIGHPRI;
	}
	tx_queue = efx_get_tx_queue(efx, index, type);

	return efx_enqueue_skb(tx_queue, skb);
}
Exemplo n.º 11
0
static void siena_mcdi_request(struct efx_nic *efx,
			       const efx_dword_t *hdr, size_t hdr_len,
			       const efx_dword_t *sdu, size_t sdu_len)
{
	unsigned pdu = FR_CZ_MC_TREG_SMEM + MCDI_PDU(efx);
	unsigned doorbell = FR_CZ_MC_TREG_SMEM + MCDI_DOORBELL(efx);
	unsigned int i;
	unsigned int inlen_dw = DIV_ROUND_UP(sdu_len, 4);

	EFX_WARN_ON_PARANOID(hdr_len != 4);

	efx_writed(efx, hdr, pdu);

	for (i = 0; i < inlen_dw; i++)
		efx_writed(efx, &sdu[i], pdu + hdr_len + 4 * i);

	/* Ensure the request is written out before the doorbell */
	wmb();

	/* ring the doorbell with a distinctive value */
	_efx_writed(efx, (__force __le32) 0x45789abc, doorbell);
}
Exemplo n.º 12
0
void efx_mcdi_process_link_change(struct efx_nic *efx, efx_qword_t *ev)
{
	u32 flags, fcntl, speed, lpa;

	speed = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_SPEED);
	EFX_WARN_ON_PARANOID(speed >= ARRAY_SIZE(efx_mcdi_event_link_speed));
	speed = efx_mcdi_event_link_speed[speed];

	flags = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_LINK_FLAGS);
	fcntl = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_FCNTL);
	lpa = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_LP_CAP);

	/* efx->link_state is only modified by efx_mcdi_phy_get_link(),
	 * which is only run after flushing the event queues. Therefore, it
	 * is safe to modify the link state outside of the mac_lock here.
	 */
	efx_mcdi_phy_decode_link(efx, &efx->link_state, speed, flags, fcntl);

	efx_mcdi_phy_check_fcntl(efx, lpa);

	efx_link_status_changed(efx);
}