Commit 09bba1ca authored by David S. Miller's avatar David S. Miller

Merge branch 'sunvnet-jumbograms'

David L Stevens says:

====================
sunvnet: add jumbo frames support

This patch set updates the sunvnet driver to version 1.6 of the VIO protocol
to support per-port exchange of MTU information and allow non-standard MTU
sizes, including jumbo frames.

Using large MTUs shows a nearly 5X throughput improvement Linux-Solaris
and > 10X throughput improvement Linux-Linux.

Changes from v8:
	-add a short timeout to free pending skbs if a new transmit doesn't
	 do it first per Dave Miller <davem@davemloft.net>
Changes from v7:
	-handle skb allocation failures in vnet_skb_shape()
	 per Dave Miller <davem@davemloft.net>
Changes from v6:
	-made kernel transmit path zero-copy to remove memory n^2 scaling issue
	 raised by Raghuram Kothakota <Raghuram.Kothakota@oracle.com>
Changes from v5:
	- fixed comment per Sowmini Varadhan <sowmini.varadhan@oracle.com>
Changes from v4:
	- changed VNET_MAXPACKET per David Laight <David.Laight@ACULAB.COM>
	- added cookies to support non-contiguous buffers of max size
Changes from v3:
	- added version functions per Dave Miller <davem@davemloft.net>
	- moved rmtu to vnet_port per Dave Miller <davem@davemloft.net>
	- explicitly set options bits and capability flags to 0 per
		Raghuram Kothakota <Raghuram.Kothakota@oracle.com>
Changes from v2:
	- make checkpatch clean
Changes from v1:
	- fix brace formatting per Dave Miller <davem@davemloft.net>
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents a12a601e a2b78e9b
......@@ -65,6 +65,7 @@ struct vio_dring_register {
u16 options;
#define VIO_TX_DRING 0x0001
#define VIO_RX_DRING 0x0002
#define VIO_RX_DRING_DATA 0x0004
u16 resv;
u32 num_cookies;
struct ldc_trans_cookie cookies[0];
......@@ -80,6 +81,8 @@ struct vio_dring_unregister {
#define VIO_PKT_MODE 0x01 /* Packet based transfer */
#define VIO_DESC_MODE 0x02 /* In-band descriptors */
#define VIO_DRING_MODE 0x03 /* Descriptor rings */
/* in vers >= 1.2, VIO_DRING_MODE is 0x04 and transfer mode is a bitmask */
#define VIO_NEW_DRING_MODE 0x04
struct vio_dring_data {
struct vio_msg_tag tag;
......@@ -205,10 +208,20 @@ struct vio_net_attr_info {
u8 addr_type;
#define VNET_ADDR_ETHERMAC 0x01
u16 ack_freq;
u32 resv1;
u8 plnk_updt;
#define PHYSLINK_UPDATE_NONE 0x00
#define PHYSLINK_UPDATE_STATE 0x01
#define PHYSLINK_UPDATE_STATE_ACK 0x02
#define PHYSLINK_UPDATE_STATE_NACK 0x03
u8 options;
u16 resv1;
u64 addr;
u64 mtu;
u64 resv2[3];
u16 cflags;
#define VNET_LSO_IPV4_CAPAB 0x0001
u16 ipv4_lso_maxlen;
u32 resv2;
u64 resv3[2];
};
#define VNET_NUM_MCAST 7
......@@ -366,6 +379,33 @@ struct vio_driver_state {
struct vio_driver_ops *ops;
};
static inline bool vio_version_before(struct vio_driver_state *vio,
u16 major, u16 minor)
{
u32 have = (u32)vio->ver.major << 16 | vio->ver.minor;
u32 want = (u32)major << 16 | minor;
return have < want;
}
static inline bool vio_version_after(struct vio_driver_state *vio,
u16 major, u16 minor)
{
u32 have = (u32)vio->ver.major << 16 | vio->ver.minor;
u32 want = (u32)major << 16 | minor;
return have > want;
}
static inline bool vio_version_after_eq(struct vio_driver_state *vio,
u16 major, u16 minor)
{
u32 have = (u32)vio->ver.major << 16 | vio->ver.minor;
u32 want = (u32)major << 16 | minor;
return have >= want;
}
#define viodbg(TYPE, f, a...) \
do { if (vio->debug & VIO_DEBUG_##TYPE) \
printk(KERN_INFO "vio: ID[%lu] " f, \
......
......@@ -2159,7 +2159,7 @@ int ldc_map_single(struct ldc_channel *lp,
state.pte_idx = (base - iommu->page_table);
state.nc = 0;
fill_cookies(&state, (pa & PAGE_MASK), (pa & ~PAGE_MASK), len);
BUG_ON(state.nc != 1);
BUG_ON(state.nc > ncookies);
return state.nc;
}
......
......@@ -426,6 +426,13 @@ static int process_dreg_info(struct vio_driver_state *vio,
if (vio->dr_state & VIO_DR_STATE_RXREG)
goto send_nack;
/* v1.6 and higher, ACK with desired, supported mode, or NACK */
if (vio_version_after_eq(vio, 1, 6)) {
if (!(pkt->options & VIO_TX_DRING))
goto send_nack;
pkt->options = VIO_TX_DRING;
}
BUG_ON(vio->desc_buf);
vio->desc_buf = kzalloc(pkt->descr_size, GFP_ATOMIC);
......@@ -453,8 +460,11 @@ static int process_dreg_info(struct vio_driver_state *vio,
pkt->tag.stype = VIO_SUBTYPE_ACK;
pkt->dring_ident = ++dr->ident;
viodbg(HS, "SEND DRING_REG ACK ident[%llx]\n",
(unsigned long long) pkt->dring_ident);
viodbg(HS, "SEND DRING_REG ACK ident[%llx] "
"ndesc[%u] dsz[%u] opt[0x%x] ncookies[%u]\n",
(unsigned long long) pkt->dring_ident,
pkt->num_descr, pkt->descr_size, pkt->options,
pkt->num_cookies);
len = (sizeof(*pkt) +
(dr->ncookies * sizeof(struct ldc_trans_cookie)));
......
This diff is collapsed.
......@@ -11,6 +11,12 @@
*/
#define VNET_TX_TIMEOUT (5 * HZ)
/* length of time (or less) we expect pending descriptors to be marked
* as VIO_DESC_DONE and skbs ready to be freed
*/
#define VNET_CLEAN_TIMEOUT ((HZ/100)+1)
#define VNET_MAXPACKET (65535ULL + ETH_HLEN + VLAN_HLEN)
#define VNET_TX_RING_SIZE 512
#define VNET_TX_WAKEUP_THRESH(dr) ((dr)->pending / 4)
......@@ -20,10 +26,12 @@
*/
#define VNET_PACKET_SKIP 6
#define VNET_MAXCOOKIES (VNET_MAXPACKET/PAGE_SIZE + 1)
struct vnet_tx_entry {
void *buf;
struct sk_buff *skb;
unsigned int ncookies;
struct ldc_trans_cookie cookies[2];
struct ldc_trans_cookie cookies[VNET_MAXCOOKIES];
};
struct vnet;
......@@ -44,6 +52,10 @@ struct vnet_port {
u32 stop_rx_idx;
bool stop_rx;
bool start_cons;
struct timer_list clean_timer;
u64 rmtu;
};
static inline struct vnet_port *to_vnet_port(struct vio_driver_state *vio)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment