diff options
author | David L Stevens <david.stevens@oracle.com> | 2014-09-29 19:47:59 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-09-30 17:17:08 -0400 |
commit | 163a4e7473061388bba0899a1a063bae44e1715a (patch) | |
tree | cee8585401e0efb14d3ea54c436b403f144c4513 | |
parent | 9d0713edf72461438bc3526e4ea55fec47754cd9 (diff) |
sparc: VIO protocol version 1.6
Add VIO protocol version 1.6 interfaces.
Signed-off-by: David L Stevens <david.stevens@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | arch/sparc/include/asm/vio.h | 44 | ||||
-rw-r--r-- | arch/sparc/kernel/viohs.c | 14 |
2 files changed, 54 insertions, 4 deletions
diff --git a/arch/sparc/include/asm/vio.h b/arch/sparc/include/asm/vio.h index e0f6c399f1d0..6b135a8ab07b 100644 --- a/arch/sparc/include/asm/vio.h +++ b/arch/sparc/include/asm/vio.h | |||
@@ -65,6 +65,7 @@ struct vio_dring_register { | |||
65 | u16 options; | 65 | u16 options; |
66 | #define VIO_TX_DRING 0x0001 | 66 | #define VIO_TX_DRING 0x0001 |
67 | #define VIO_RX_DRING 0x0002 | 67 | #define VIO_RX_DRING 0x0002 |
68 | #define VIO_RX_DRING_DATA 0x0004 | ||
68 | u16 resv; | 69 | u16 resv; |
69 | u32 num_cookies; | 70 | u32 num_cookies; |
70 | struct ldc_trans_cookie cookies[0]; | 71 | struct ldc_trans_cookie cookies[0]; |
@@ -80,6 +81,8 @@ struct vio_dring_unregister { | |||
80 | #define VIO_PKT_MODE 0x01 /* Packet based transfer */ | 81 | #define VIO_PKT_MODE 0x01 /* Packet based transfer */ |
81 | #define VIO_DESC_MODE 0x02 /* In-band descriptors */ | 82 | #define VIO_DESC_MODE 0x02 /* In-band descriptors */ |
82 | #define VIO_DRING_MODE 0x03 /* Descriptor rings */ | 83 | #define VIO_DRING_MODE 0x03 /* Descriptor rings */ |
84 | /* in vers >= 1.2, VIO_DRING_MODE is 0x04 and transfer mode is a bitmask */ | ||
85 | #define VIO_NEW_DRING_MODE 0x04 | ||
83 | 86 | ||
84 | struct vio_dring_data { | 87 | struct vio_dring_data { |
85 | struct vio_msg_tag tag; | 88 | struct vio_msg_tag tag; |
@@ -205,10 +208,20 @@ struct vio_net_attr_info { | |||
205 | u8 addr_type; | 208 | u8 addr_type; |
206 | #define VNET_ADDR_ETHERMAC 0x01 | 209 | #define VNET_ADDR_ETHERMAC 0x01 |
207 | u16 ack_freq; | 210 | u16 ack_freq; |
208 | u32 resv1; | 211 | u8 plnk_updt; |
212 | #define PHYSLINK_UPDATE_NONE 0x00 | ||
213 | #define PHYSLINK_UPDATE_STATE 0x01 | ||
214 | #define PHYSLINK_UPDATE_STATE_ACK 0x02 | ||
215 | #define PHYSLINK_UPDATE_STATE_NACK 0x03 | ||
216 | u8 options; | ||
217 | u16 resv1; | ||
209 | u64 addr; | 218 | u64 addr; |
210 | u64 mtu; | 219 | u64 mtu; |
211 | u64 resv2[3]; | 220 | u16 cflags; |
221 | #define VNET_LSO_IPV4_CAPAB 0x0001 | ||
222 | u16 ipv4_lso_maxlen; | ||
223 | u32 resv2; | ||
224 | u64 resv3[2]; | ||
212 | }; | 225 | }; |
213 | 226 | ||
214 | #define VNET_NUM_MCAST 7 | 227 | #define VNET_NUM_MCAST 7 |
@@ -366,6 +379,33 @@ struct vio_driver_state { | |||
366 | struct vio_driver_ops *ops; | 379 | struct vio_driver_ops *ops; |
367 | }; | 380 | }; |
368 | 381 | ||
382 | static inline bool vio_version_before(struct vio_driver_state *vio, | ||
383 | u16 major, u16 minor) | ||
384 | { | ||
385 | u32 have = (u32)vio->ver.major << 16 | vio->ver.minor; | ||
386 | u32 want = (u32)major << 16 | minor; | ||
387 | |||
388 | return have < want; | ||
389 | } | ||
390 | |||
391 | static inline bool vio_version_after(struct vio_driver_state *vio, | ||
392 | u16 major, u16 minor) | ||
393 | { | ||
394 | u32 have = (u32)vio->ver.major << 16 | vio->ver.minor; | ||
395 | u32 want = (u32)major << 16 | minor; | ||
396 | |||
397 | return have > want; | ||
398 | } | ||
399 | |||
400 | static inline bool vio_version_after_eq(struct vio_driver_state *vio, | ||
401 | u16 major, u16 minor) | ||
402 | { | ||
403 | u32 have = (u32)vio->ver.major << 16 | vio->ver.minor; | ||
404 | u32 want = (u32)major << 16 | minor; | ||
405 | |||
406 | return have >= want; | ||
407 | } | ||
408 | |||
369 | #define viodbg(TYPE, f, a...) \ | 409 | #define viodbg(TYPE, f, a...) \ |
370 | do { if (vio->debug & VIO_DEBUG_##TYPE) \ | 410 | do { if (vio->debug & VIO_DEBUG_##TYPE) \ |
371 | printk(KERN_INFO "vio: ID[%lu] " f, \ | 411 | printk(KERN_INFO "vio: ID[%lu] " f, \ |
diff --git a/arch/sparc/kernel/viohs.c b/arch/sparc/kernel/viohs.c index 9c5fbd0b8a04..526fcb5d8ce9 100644 --- a/arch/sparc/kernel/viohs.c +++ b/arch/sparc/kernel/viohs.c | |||
@@ -426,6 +426,13 @@ static int process_dreg_info(struct vio_driver_state *vio, | |||
426 | if (vio->dr_state & VIO_DR_STATE_RXREG) | 426 | if (vio->dr_state & VIO_DR_STATE_RXREG) |
427 | goto send_nack; | 427 | goto send_nack; |
428 | 428 | ||
429 | /* v1.6 and higher, ACK with desired, supported mode, or NACK */ | ||
430 | if (vio_version_after_eq(vio, 1, 6)) { | ||
431 | if (!(pkt->options & VIO_TX_DRING)) | ||
432 | goto send_nack; | ||
433 | pkt->options = VIO_TX_DRING; | ||
434 | } | ||
435 | |||
429 | BUG_ON(vio->desc_buf); | 436 | BUG_ON(vio->desc_buf); |
430 | 437 | ||
431 | vio->desc_buf = kzalloc(pkt->descr_size, GFP_ATOMIC); | 438 | vio->desc_buf = kzalloc(pkt->descr_size, GFP_ATOMIC); |
@@ -453,8 +460,11 @@ static int process_dreg_info(struct vio_driver_state *vio, | |||
453 | pkt->tag.stype = VIO_SUBTYPE_ACK; | 460 | pkt->tag.stype = VIO_SUBTYPE_ACK; |
454 | pkt->dring_ident = ++dr->ident; | 461 | pkt->dring_ident = ++dr->ident; |
455 | 462 | ||
456 | viodbg(HS, "SEND DRING_REG ACK ident[%llx]\n", | 463 | viodbg(HS, "SEND DRING_REG ACK ident[%llx] " |
457 | (unsigned long long) pkt->dring_ident); | 464 | "ndesc[%u] dsz[%u] opt[0x%x] ncookies[%u]\n", |
465 | (unsigned long long) pkt->dring_ident, | ||
466 | pkt->num_descr, pkt->descr_size, pkt->options, | ||
467 | pkt->num_cookies); | ||
458 | 468 | ||
459 | len = (sizeof(*pkt) + | 469 | len = (sizeof(*pkt) + |
460 | (dr->ncookies * sizeof(struct ldc_trans_cookie))); | 470 | (dr->ncookies * sizeof(struct ldc_trans_cookie))); |