126570aafSAsias He #include "kvm/uip.h"
226570aafSAsias He
326570aafSAsias He #include <linux/kernel.h>
426570aafSAsias He #include <linux/list.h>
526570aafSAsias He
uip_buf_get_used(struct uip_info * info)626570aafSAsias He struct uip_buf *uip_buf_get_used(struct uip_info *info)
726570aafSAsias He {
826570aafSAsias He struct uip_buf *buf;
926570aafSAsias He bool found = false;
1026570aafSAsias He
1126570aafSAsias He mutex_lock(&info->buf_lock);
1226570aafSAsias He
1326570aafSAsias He while (!(info->buf_used_nr > 0))
14*d3476f7dSSasha Levin pthread_cond_wait(&info->buf_used_cond, &info->buf_lock.mutex);
1526570aafSAsias He
1626570aafSAsias He list_for_each_entry(buf, &info->buf_head, list) {
1726570aafSAsias He if (buf->status == UIP_BUF_STATUS_USED) {
1826570aafSAsias He /*
1926570aafSAsias He * Set status to INUSE immediately to prevent
2026570aafSAsias He * someone from using this buf until we free it
2126570aafSAsias He */
2226570aafSAsias He buf->status = UIP_BUF_STATUS_INUSE;
2326570aafSAsias He info->buf_used_nr--;
2426570aafSAsias He found = true;
2526570aafSAsias He break;
2626570aafSAsias He }
2726570aafSAsias He }
2826570aafSAsias He
2926570aafSAsias He mutex_unlock(&info->buf_lock);
3026570aafSAsias He
3126570aafSAsias He return found ? buf : NULL;
3226570aafSAsias He }
3326570aafSAsias He
uip_buf_get_free(struct uip_info * info)3426570aafSAsias He struct uip_buf *uip_buf_get_free(struct uip_info *info)
3526570aafSAsias He {
3626570aafSAsias He struct uip_buf *buf;
3726570aafSAsias He bool found = false;
3826570aafSAsias He
3926570aafSAsias He mutex_lock(&info->buf_lock);
4026570aafSAsias He
4126570aafSAsias He while (!(info->buf_free_nr > 0))
42*d3476f7dSSasha Levin pthread_cond_wait(&info->buf_free_cond, &info->buf_lock.mutex);
4326570aafSAsias He
4426570aafSAsias He list_for_each_entry(buf, &info->buf_head, list) {
4526570aafSAsias He if (buf->status == UIP_BUF_STATUS_FREE) {
4626570aafSAsias He /*
4726570aafSAsias He * Set status to INUSE immediately to prevent
4826570aafSAsias He * someone from using this buf until we free it
4926570aafSAsias He */
5026570aafSAsias He buf->status = UIP_BUF_STATUS_INUSE;
5126570aafSAsias He info->buf_free_nr--;
5226570aafSAsias He found = true;
5326570aafSAsias He break;
5426570aafSAsias He }
5526570aafSAsias He }
5626570aafSAsias He
5726570aafSAsias He mutex_unlock(&info->buf_lock);
5826570aafSAsias He
5926570aafSAsias He return found ? buf : NULL;
6026570aafSAsias He }
6126570aafSAsias He
uip_buf_set_used(struct uip_info * info,struct uip_buf * buf)6226570aafSAsias He struct uip_buf *uip_buf_set_used(struct uip_info *info, struct uip_buf *buf)
6326570aafSAsias He {
6426570aafSAsias He mutex_lock(&info->buf_lock);
6526570aafSAsias He
6626570aafSAsias He buf->status = UIP_BUF_STATUS_USED;
6726570aafSAsias He info->buf_used_nr++;
6826570aafSAsias He pthread_cond_signal(&info->buf_used_cond);
6926570aafSAsias He
7026570aafSAsias He mutex_unlock(&info->buf_lock);
7126570aafSAsias He
7226570aafSAsias He return buf;
7326570aafSAsias He }
7426570aafSAsias He
uip_buf_set_free(struct uip_info * info,struct uip_buf * buf)7526570aafSAsias He struct uip_buf *uip_buf_set_free(struct uip_info *info, struct uip_buf *buf)
7626570aafSAsias He {
7726570aafSAsias He mutex_lock(&info->buf_lock);
7826570aafSAsias He
7926570aafSAsias He buf->status = UIP_BUF_STATUS_FREE;
8026570aafSAsias He info->buf_free_nr++;
8126570aafSAsias He pthread_cond_signal(&info->buf_free_cond);
8226570aafSAsias He
8326570aafSAsias He mutex_unlock(&info->buf_lock);
8426570aafSAsias He
8526570aafSAsias He return buf;
8626570aafSAsias He }
8726570aafSAsias He
uip_buf_clone(struct uip_tx_arg * arg)8826570aafSAsias He struct uip_buf *uip_buf_clone(struct uip_tx_arg *arg)
8926570aafSAsias He {
9026570aafSAsias He struct uip_buf *buf;
9126570aafSAsias He struct uip_eth *eth2;
9226570aafSAsias He struct uip_info *info;
9326570aafSAsias He
9426570aafSAsias He info = arg->info;
9526570aafSAsias He
9626570aafSAsias He /*
9726570aafSAsias He * Get buffer from device to guest
9826570aafSAsias He */
9926570aafSAsias He buf = uip_buf_get_free(info);
10026570aafSAsias He
10126570aafSAsias He /*
10226570aafSAsias He * Clone buffer
10326570aafSAsias He */
10426570aafSAsias He memcpy(buf->vnet, arg->vnet, arg->vnet_len);
10526570aafSAsias He memcpy(buf->eth, arg->eth, arg->eth_len);
10626570aafSAsias He buf->vnet_len = arg->vnet_len;
10726570aafSAsias He buf->eth_len = arg->eth_len;
10826570aafSAsias He
10926570aafSAsias He eth2 = (struct uip_eth *)buf->eth;
11026570aafSAsias He eth2->src = info->host_mac;
11126570aafSAsias He eth2->dst = arg->eth->src;
11226570aafSAsias He
11326570aafSAsias He return buf;
11426570aafSAsias He }
115