diff options
author | Shahed Shaikh <shahed.shaikh@qlogic.com> | 2013-03-08 04:53:49 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-03-09 16:09:18 -0500 |
commit | a96227e66f0a0361d96885042629bf60eb6a4b39 (patch) | |
tree | 961edc48d145593b704b2ef2fe951fd544f65c32 /drivers/net/ethernet | |
parent | 23bdbc80e1d17e5ea00138bae1f7f534faf4bb27 (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.c | 106 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | 17 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 33 |
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 | */ |
23 | struct qlcnic_sds_mbx { | 23 | struct 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 | */ |
41 | struct qlcnic_rds_mbx { | 53 | struct 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 | */ |
63 | struct qlcnic_rcv_mbx_out { | 84 | struct 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 | ||
75 | struct qlcnic_add_rings_mbx_out { | 106 | struct 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 | */ |
90 | struct qlcnic_tx_mbx { | 127 | struct 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 | |||
104 | struct qlcnic_tx_mbx_out { | 151 | struct 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 | ||
111 | static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = { | 164 | static 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 | ||
96 | struct qlcnic_macvlan_mbx { | 96 | struct 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 | ||
101 | struct qlc_83xx_fw_info { | 116 | struct 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 */ |
33 | struct qlc_83xx_reset_hdr { | 33 | struct 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. */ |
45 | struct qlc_83xx_entry_hdr { | 56 | struct 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 */ |