aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet
diff options
context:
space:
mode:
authorShahed Shaikh <shahed.shaikh@qlogic.com>2013-03-08 04:53:49 -0500
committerDavid S. Miller <davem@davemloft.net>2013-03-09 16:09:18 -0500
commita96227e66f0a0361d96885042629bf60eb6a4b39 (patch)
tree961edc48d145593b704b2ef2fe951fd544f65c32 /drivers/net/ethernet
parent23bdbc80e1d17e5ea00138bae1f7f534faf4bb27 (diff)
qlcnic: Fix endian issues in 83xx driver
o Split mailbox structure elements on boundary of adapter register size i.e. 32bit. o Shuffle the position of structure elements based on CPU endianness. Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c106
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h17
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c33
3 files changed, 130 insertions, 26 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index cd5ae8813cb3..41c02ba7648c 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -15,36 +15,57 @@
15#define RSS_HASHTYPE_IP_TCP 0x3 15#define RSS_HASHTYPE_IP_TCP 0x3
16 16
17/* status descriptor mailbox data 17/* status descriptor mailbox data
18 * @phy_addr: physical address of buffer 18 * @phy_addr_{low|high}: physical address of buffer
19 * @sds_ring_size: buffer size 19 * @sds_ring_size: buffer size
20 * @intrpt_id: interrupt id 20 * @intrpt_id: interrupt id
21 * @intrpt_val: source of interrupt 21 * @intrpt_val: source of interrupt
22 */ 22 */
23struct qlcnic_sds_mbx { 23struct qlcnic_sds_mbx {
24 u64 phy_addr; 24 u32 phy_addr_low;
25 u8 rsvd1[16]; 25 u32 phy_addr_high;
26 u32 rsvd1[4];
27#if defined(__LITTLE_ENDIAN)
26 u16 sds_ring_size; 28 u16 sds_ring_size;
27 u16 rsvd2[3]; 29 u16 rsvd2;
30 u16 rsvd3[2];
28 u16 intrpt_id; 31 u16 intrpt_id;
29 u8 intrpt_val; 32 u8 intrpt_val;
30 u8 rsvd3[5]; 33 u8 rsvd4;
34#elif defined(__BIG_ENDIAN)
35 u16 rsvd2;
36 u16 sds_ring_size;
37 u16 rsvd3[2];
38 u8 rsvd4;
39 u8 intrpt_val;
40 u16 intrpt_id;
41#endif
42 u32 rsvd5;
31} __packed; 43} __packed;
32 44
33/* receive descriptor buffer data 45/* receive descriptor buffer data
34 * phy_addr_reg: physical address of regular buffer 46 * phy_addr_reg_{low|high}: physical address of regular buffer
35 * phy_addr_jmb: physical address of jumbo buffer 47 * phy_addr_jmb_{low|high}: physical address of jumbo buffer
36 * reg_ring_sz: size of regular buffer 48 * reg_ring_sz: size of regular buffer
37 * reg_ring_len: no. of entries in regular buffer 49 * reg_ring_len: no. of entries in regular buffer
38 * jmb_ring_len: no. of entries in jumbo buffer 50 * jmb_ring_len: no. of entries in jumbo buffer
39 * jmb_ring_sz: size of jumbo buffer 51 * jmb_ring_sz: size of jumbo buffer
40 */ 52 */
41struct qlcnic_rds_mbx { 53struct qlcnic_rds_mbx {
42 u64 phy_addr_reg; 54 u32 phy_addr_reg_low;
43 u64 phy_addr_jmb; 55 u32 phy_addr_reg_high;
56 u32 phy_addr_jmb_low;
57 u32 phy_addr_jmb_high;
58#if defined(__LITTLE_ENDIAN)
44 u16 reg_ring_sz; 59 u16 reg_ring_sz;
45 u16 reg_ring_len; 60 u16 reg_ring_len;
46 u16 jmb_ring_sz; 61 u16 jmb_ring_sz;
47 u16 jmb_ring_len; 62 u16 jmb_ring_len;
63#elif defined(__BIG_ENDIAN)
64 u16 reg_ring_len;
65 u16 reg_ring_sz;
66 u16 jmb_ring_len;
67 u16 jmb_ring_sz;
68#endif
48} __packed; 69} __packed;
49 70
50/* host producers for regular and jumbo rings */ 71/* host producers for regular and jumbo rings */
@@ -61,6 +82,7 @@ struct __host_producer_mbx {
61 * @phy_port: physical port id 82 * @phy_port: physical port id
62 */ 83 */
63struct qlcnic_rcv_mbx_out { 84struct qlcnic_rcv_mbx_out {
85#if defined(__LITTLE_ENDIAN)
64 u8 rcv_num; 86 u8 rcv_num;
65 u8 sts_num; 87 u8 sts_num;
66 u16 ctx_id; 88 u16 ctx_id;
@@ -68,32 +90,56 @@ struct qlcnic_rcv_mbx_out {
68 u8 num_pci_func; 90 u8 num_pci_func;
69 u8 phy_port; 91 u8 phy_port;
70 u8 vport_id; 92 u8 vport_id;
93#elif defined(__BIG_ENDIAN)
94 u16 ctx_id;
95 u8 sts_num;
96 u8 rcv_num;
97 u8 vport_id;
98 u8 phy_port;
99 u8 num_pci_func;
100 u8 state;
101#endif
71 u32 host_csmr[QLCNIC_MAX_RING_SETS]; 102 u32 host_csmr[QLCNIC_MAX_RING_SETS];
72 struct __host_producer_mbx host_prod[QLCNIC_MAX_RING_SETS]; 103 struct __host_producer_mbx host_prod[QLCNIC_MAX_RING_SETS];
73} __packed; 104} __packed;
74 105
75struct qlcnic_add_rings_mbx_out { 106struct qlcnic_add_rings_mbx_out {
107#if defined(__LITTLE_ENDIAN)
76 u8 rcv_num; 108 u8 rcv_num;
77 u8 sts_num; 109 u8 sts_num;
78 u16 ctx_id; 110 u16 ctx_id;
111#elif defined(__BIG_ENDIAN)
112 u16 ctx_id;
113 u8 sts_num;
114 u8 rcv_num;
115#endif
79 u32 host_csmr[QLCNIC_MAX_RING_SETS]; 116 u32 host_csmr[QLCNIC_MAX_RING_SETS];
80 struct __host_producer_mbx host_prod[QLCNIC_MAX_RING_SETS]; 117 struct __host_producer_mbx host_prod[QLCNIC_MAX_RING_SETS];
81} __packed; 118} __packed;
82 119
83/* Transmit context mailbox inbox registers 120/* Transmit context mailbox inbox registers
84 * @phys_addr: DMA address of the transmit buffer 121 * @phys_addr_{low|high}: DMA address of the transmit buffer
85 * @cnsmr_index: host consumer index 122 * @cnsmr_index_{low|high}: host consumer index
86 * @size: legth of transmit buffer ring 123 * @size: legth of transmit buffer ring
87 * @intr_id: interrput id 124 * @intr_id: interrput id
88 * @src: src of interrupt 125 * @src: src of interrupt
89 */ 126 */
90struct qlcnic_tx_mbx { 127struct qlcnic_tx_mbx {
91 u64 phys_addr; 128 u32 phys_addr_low;
92 u64 cnsmr_index; 129 u32 phys_addr_high;
130 u32 cnsmr_index_low;
131 u32 cnsmr_index_high;
132#if defined(__LITTLE_ENDIAN)
93 u16 size; 133 u16 size;
94 u16 intr_id; 134 u16 intr_id;
95 u8 src; 135 u8 src;
96 u8 rsvd[3]; 136 u8 rsvd[3];
137#elif defined(__BIG_ENDIAN)
138 u16 intr_id;
139 u16 size;
140 u8 rsvd[3];
141 u8 src;
142#endif
97} __packed; 143} __packed;
98 144
99/* Transmit context mailbox outbox registers 145/* Transmit context mailbox outbox registers
@@ -101,11 +147,18 @@ struct qlcnic_tx_mbx {
101 * @ctx_id: transmit context id 147 * @ctx_id: transmit context id
102 * @state: state of the transmit context 148 * @state: state of the transmit context
103 */ 149 */
150
104struct qlcnic_tx_mbx_out { 151struct qlcnic_tx_mbx_out {
105 u32 host_prod; 152 u32 host_prod;
153#if defined(__LITTLE_ENDIAN)
106 u16 ctx_id; 154 u16 ctx_id;
107 u8 state; 155 u8 state;
108 u8 rsvd; 156 u8 rsvd;
157#elif defined(__BIG_ENDIAN)
158 u8 rsvd;
159 u8 state;
160 u16 ctx_id;
161#endif
109} __packed; 162} __packed;
110 163
111static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = { 164static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = {
@@ -1004,7 +1057,8 @@ static int qlcnic_83xx_add_rings(struct qlcnic_adapter *adapter)
1004 sds = &recv_ctx->sds_rings[i]; 1057 sds = &recv_ctx->sds_rings[i];
1005 sds->consumer = 0; 1058 sds->consumer = 0;
1006 memset(sds->desc_head, 0, STATUS_DESC_RINGSIZE(sds)); 1059 memset(sds->desc_head, 0, STATUS_DESC_RINGSIZE(sds));
1007 sds_mbx.phy_addr = sds->phys_addr; 1060 sds_mbx.phy_addr_low = LSD(sds->phys_addr);
1061 sds_mbx.phy_addr_high = MSD(sds->phys_addr);
1008 sds_mbx.sds_ring_size = sds->num_desc; 1062 sds_mbx.sds_ring_size = sds->num_desc;
1009 1063
1010 if (adapter->flags & QLCNIC_MSIX_ENABLED) 1064 if (adapter->flags & QLCNIC_MSIX_ENABLED)
@@ -1090,7 +1144,8 @@ int qlcnic_83xx_create_rx_ctx(struct qlcnic_adapter *adapter)
1090 sds = &recv_ctx->sds_rings[i]; 1144 sds = &recv_ctx->sds_rings[i];
1091 sds->consumer = 0; 1145 sds->consumer = 0;
1092 memset(sds->desc_head, 0, STATUS_DESC_RINGSIZE(sds)); 1146 memset(sds->desc_head, 0, STATUS_DESC_RINGSIZE(sds));
1093 sds_mbx.phy_addr = sds->phys_addr; 1147 sds_mbx.phy_addr_low = LSD(sds->phys_addr);
1148 sds_mbx.phy_addr_high = MSD(sds->phys_addr);
1094 sds_mbx.sds_ring_size = sds->num_desc; 1149 sds_mbx.sds_ring_size = sds->num_desc;
1095 if (adapter->flags & QLCNIC_MSIX_ENABLED) 1150 if (adapter->flags & QLCNIC_MSIX_ENABLED)
1096 intrpt_id = ahw->intr_tbl[i].id; 1151 intrpt_id = ahw->intr_tbl[i].id;
@@ -1110,13 +1165,15 @@ int qlcnic_83xx_create_rx_ctx(struct qlcnic_adapter *adapter)
1110 rds = &recv_ctx->rds_rings[0]; 1165 rds = &recv_ctx->rds_rings[0];
1111 rds->producer = 0; 1166 rds->producer = 0;
1112 memset(&rds_mbx, 0, rds_mbx_size); 1167 memset(&rds_mbx, 0, rds_mbx_size);
1113 rds_mbx.phy_addr_reg = rds->phys_addr; 1168 rds_mbx.phy_addr_reg_low = LSD(rds->phys_addr);
1169 rds_mbx.phy_addr_reg_high = MSD(rds->phys_addr);
1114 rds_mbx.reg_ring_sz = rds->dma_size; 1170 rds_mbx.reg_ring_sz = rds->dma_size;
1115 rds_mbx.reg_ring_len = rds->num_desc; 1171 rds_mbx.reg_ring_len = rds->num_desc;
1116 /* Jumbo ring */ 1172 /* Jumbo ring */
1117 rds = &recv_ctx->rds_rings[1]; 1173 rds = &recv_ctx->rds_rings[1];
1118 rds->producer = 0; 1174 rds->producer = 0;
1119 rds_mbx.phy_addr_jmb = rds->phys_addr; 1175 rds_mbx.phy_addr_jmb_low = LSD(rds->phys_addr);
1176 rds_mbx.phy_addr_jmb_high = MSD(rds->phys_addr);
1120 rds_mbx.jmb_ring_sz = rds->dma_size; 1177 rds_mbx.jmb_ring_sz = rds->dma_size;
1121 rds_mbx.jmb_ring_len = rds->num_desc; 1178 rds_mbx.jmb_ring_len = rds->num_desc;
1122 buf = &cmd.req.arg[index]; 1179 buf = &cmd.req.arg[index];
@@ -1182,8 +1239,10 @@ int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *adapter,
1182 memset(&mbx, 0, sizeof(struct qlcnic_tx_mbx)); 1239 memset(&mbx, 0, sizeof(struct qlcnic_tx_mbx));
1183 1240
1184 /* setup mailbox inbox registerss */ 1241 /* setup mailbox inbox registerss */
1185 mbx.phys_addr = tx->phys_addr; 1242 mbx.phys_addr_low = LSD(tx->phys_addr);
1186 mbx.cnsmr_index = tx->hw_cons_phys_addr; 1243 mbx.phys_addr_high = MSD(tx->phys_addr);
1244 mbx.cnsmr_index_low = LSD(tx->hw_cons_phys_addr);
1245 mbx.cnsmr_index_high = MSD(tx->hw_cons_phys_addr);
1187 mbx.size = tx->num_desc; 1246 mbx.size = tx->num_desc;
1188 if (adapter->flags & QLCNIC_MSIX_ENABLED) 1247 if (adapter->flags & QLCNIC_MSIX_ENABLED)
1189 msix_id = ahw->intr_tbl[adapter->max_sds_rings + ring].id; 1248 msix_id = ahw->intr_tbl[adapter->max_sds_rings + ring].id;
@@ -1713,7 +1772,12 @@ int qlcnic_83xx_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr,
1713 (adapter->recv_ctx->context_id << 16); 1772 (adapter->recv_ctx->context_id << 16);
1714 1773
1715 mv.vlan = le16_to_cpu(vlan_id); 1774 mv.vlan = le16_to_cpu(vlan_id);
1716 memcpy(&mv.mac, addr, ETH_ALEN); 1775 mv.mac_addr0 = addr[0];
1776 mv.mac_addr1 = addr[1];
1777 mv.mac_addr2 = addr[2];
1778 mv.mac_addr3 = addr[3];
1779 mv.mac_addr4 = addr[4];
1780 mv.mac_addr5 = addr[5];
1717 buf = &cmd.req.arg[2]; 1781 buf = &cmd.req.arg[2];
1718 memcpy(buf, &mv, sizeof(struct qlcnic_macvlan_mbx)); 1782 memcpy(buf, &mv, sizeof(struct qlcnic_macvlan_mbx));
1719 err = qlcnic_issue_cmd(adapter, &cmd); 1783 err = qlcnic_issue_cmd(adapter, &cmd);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
index 61f81f6c84a9..94e3ee0a7aa6 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
@@ -94,8 +94,23 @@ struct qlcnic_intrpt_config {
94}; 94};
95 95
96struct qlcnic_macvlan_mbx { 96struct qlcnic_macvlan_mbx {
97 u8 mac[ETH_ALEN]; 97#if defined(__LITTLE_ENDIAN)
98 u8 mac_addr0;
99 u8 mac_addr1;
100 u8 mac_addr2;
101 u8 mac_addr3;
102 u8 mac_addr4;
103 u8 mac_addr5;
98 u16 vlan; 104 u16 vlan;
105#elif defined(__BIG_ENDIAN)
106 u8 mac_addr3;
107 u8 mac_addr2;
108 u8 mac_addr1;
109 u8 mac_addr0;
110 u16 vlan;
111 u8 mac_addr5;
112 u8 mac_addr4;
113#endif
99}; 114};
100 115
101struct qlc_83xx_fw_info { 116struct qlc_83xx_fw_info {
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
index 5c033f268ca5..ba5ac69bf48e 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
@@ -31,6 +31,7 @@ static int qlcnic_83xx_restart_hw(struct qlcnic_adapter *adapter);
31 31
32/* Template header */ 32/* Template header */
33struct qlc_83xx_reset_hdr { 33struct qlc_83xx_reset_hdr {
34#if defined(__LITTLE_ENDIAN)
34 u16 version; 35 u16 version;
35 u16 signature; 36 u16 signature;
36 u16 size; 37 u16 size;
@@ -39,14 +40,31 @@ struct qlc_83xx_reset_hdr {
39 u16 checksum; 40 u16 checksum;
40 u16 init_offset; 41 u16 init_offset;
41 u16 start_offset; 42 u16 start_offset;
43#elif defined(__BIG_ENDIAN)
44 u16 signature;
45 u16 version;
46 u16 entries;
47 u16 size;
48 u16 checksum;
49 u16 hdr_size;
50 u16 start_offset;
51 u16 init_offset;
52#endif
42} __packed; 53} __packed;
43 54
44/* Command entry header. */ 55/* Command entry header. */
45struct qlc_83xx_entry_hdr { 56struct qlc_83xx_entry_hdr {
46 u16 cmd; 57#if defined(__LITTLE_ENDIAN)
47 u16 size; 58 u16 cmd;
48 u16 count; 59 u16 size;
49 u16 delay; 60 u16 count;
61 u16 delay;
62#elif defined(__BIG_ENDIAN)
63 u16 size;
64 u16 cmd;
65 u16 delay;
66 u16 count;
67#endif
50} __packed; 68} __packed;
51 69
52/* Generic poll command */ 70/* Generic poll command */
@@ -60,10 +78,17 @@ struct qlc_83xx_rmw {
60 u32 mask; 78 u32 mask;
61 u32 xor_value; 79 u32 xor_value;
62 u32 or_value; 80 u32 or_value;
81#if defined(__LITTLE_ENDIAN)
63 u8 shl; 82 u8 shl;
64 u8 shr; 83 u8 shr;
65 u8 index_a; 84 u8 index_a;
66 u8 rsvd; 85 u8 rsvd;
86#elif defined(__BIG_ENDIAN)
87 u8 rsvd;
88 u8 index_a;
89 u8 shr;
90 u8 shl;
91#endif
67} __packed; 92} __packed;
68 93
69/* Generic command with 2 DWORD */ 94/* Generic command with 2 DWORD */