mirror of
https://github.com/torvalds/linux.git
synced 2024-12-20 01:52:13 +00:00
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>
This commit is contained in:
parent
23bdbc80e1
commit
a96227e66f
@ -15,36 +15,57 @@
|
||||
#define RSS_HASHTYPE_IP_TCP 0x3
|
||||
|
||||
/* status descriptor mailbox data
|
||||
* @phy_addr: physical address of buffer
|
||||
* @phy_addr_{low|high}: physical address of buffer
|
||||
* @sds_ring_size: buffer size
|
||||
* @intrpt_id: interrupt id
|
||||
* @intrpt_val: source of interrupt
|
||||
*/
|
||||
struct qlcnic_sds_mbx {
|
||||
u64 phy_addr;
|
||||
u8 rsvd1[16];
|
||||
u32 phy_addr_low;
|
||||
u32 phy_addr_high;
|
||||
u32 rsvd1[4];
|
||||
#if defined(__LITTLE_ENDIAN)
|
||||
u16 sds_ring_size;
|
||||
u16 rsvd2[3];
|
||||
u16 rsvd2;
|
||||
u16 rsvd3[2];
|
||||
u16 intrpt_id;
|
||||
u8 intrpt_val;
|
||||
u8 rsvd3[5];
|
||||
u8 rsvd4;
|
||||
#elif defined(__BIG_ENDIAN)
|
||||
u16 rsvd2;
|
||||
u16 sds_ring_size;
|
||||
u16 rsvd3[2];
|
||||
u8 rsvd4;
|
||||
u8 intrpt_val;
|
||||
u16 intrpt_id;
|
||||
#endif
|
||||
u32 rsvd5;
|
||||
} __packed;
|
||||
|
||||
/* receive descriptor buffer data
|
||||
* phy_addr_reg: physical address of regular buffer
|
||||
* phy_addr_jmb: physical address of jumbo buffer
|
||||
* phy_addr_reg_{low|high}: physical address of regular buffer
|
||||
* phy_addr_jmb_{low|high}: physical address of jumbo buffer
|
||||
* reg_ring_sz: size of regular buffer
|
||||
* reg_ring_len: no. of entries in regular buffer
|
||||
* jmb_ring_len: no. of entries in jumbo buffer
|
||||
* jmb_ring_sz: size of jumbo buffer
|
||||
*/
|
||||
struct qlcnic_rds_mbx {
|
||||
u64 phy_addr_reg;
|
||||
u64 phy_addr_jmb;
|
||||
u32 phy_addr_reg_low;
|
||||
u32 phy_addr_reg_high;
|
||||
u32 phy_addr_jmb_low;
|
||||
u32 phy_addr_jmb_high;
|
||||
#if defined(__LITTLE_ENDIAN)
|
||||
u16 reg_ring_sz;
|
||||
u16 reg_ring_len;
|
||||
u16 jmb_ring_sz;
|
||||
u16 jmb_ring_len;
|
||||
#elif defined(__BIG_ENDIAN)
|
||||
u16 reg_ring_len;
|
||||
u16 reg_ring_sz;
|
||||
u16 jmb_ring_len;
|
||||
u16 jmb_ring_sz;
|
||||
#endif
|
||||
} __packed;
|
||||
|
||||
/* host producers for regular and jumbo rings */
|
||||
@ -61,6 +82,7 @@ struct __host_producer_mbx {
|
||||
* @phy_port: physical port id
|
||||
*/
|
||||
struct qlcnic_rcv_mbx_out {
|
||||
#if defined(__LITTLE_ENDIAN)
|
||||
u8 rcv_num;
|
||||
u8 sts_num;
|
||||
u16 ctx_id;
|
||||
@ -68,32 +90,56 @@ struct qlcnic_rcv_mbx_out {
|
||||
u8 num_pci_func;
|
||||
u8 phy_port;
|
||||
u8 vport_id;
|
||||
#elif defined(__BIG_ENDIAN)
|
||||
u16 ctx_id;
|
||||
u8 sts_num;
|
||||
u8 rcv_num;
|
||||
u8 vport_id;
|
||||
u8 phy_port;
|
||||
u8 num_pci_func;
|
||||
u8 state;
|
||||
#endif
|
||||
u32 host_csmr[QLCNIC_MAX_RING_SETS];
|
||||
struct __host_producer_mbx host_prod[QLCNIC_MAX_RING_SETS];
|
||||
} __packed;
|
||||
|
||||
struct qlcnic_add_rings_mbx_out {
|
||||
#if defined(__LITTLE_ENDIAN)
|
||||
u8 rcv_num;
|
||||
u8 sts_num;
|
||||
u16 ctx_id;
|
||||
u16 ctx_id;
|
||||
#elif defined(__BIG_ENDIAN)
|
||||
u16 ctx_id;
|
||||
u8 sts_num;
|
||||
u8 rcv_num;
|
||||
#endif
|
||||
u32 host_csmr[QLCNIC_MAX_RING_SETS];
|
||||
struct __host_producer_mbx host_prod[QLCNIC_MAX_RING_SETS];
|
||||
} __packed;
|
||||
|
||||
/* Transmit context mailbox inbox registers
|
||||
* @phys_addr: DMA address of the transmit buffer
|
||||
* @cnsmr_index: host consumer index
|
||||
* @phys_addr_{low|high}: DMA address of the transmit buffer
|
||||
* @cnsmr_index_{low|high}: host consumer index
|
||||
* @size: legth of transmit buffer ring
|
||||
* @intr_id: interrput id
|
||||
* @src: src of interrupt
|
||||
*/
|
||||
struct qlcnic_tx_mbx {
|
||||
u64 phys_addr;
|
||||
u64 cnsmr_index;
|
||||
u32 phys_addr_low;
|
||||
u32 phys_addr_high;
|
||||
u32 cnsmr_index_low;
|
||||
u32 cnsmr_index_high;
|
||||
#if defined(__LITTLE_ENDIAN)
|
||||
u16 size;
|
||||
u16 intr_id;
|
||||
u8 src;
|
||||
u8 rsvd[3];
|
||||
#elif defined(__BIG_ENDIAN)
|
||||
u16 intr_id;
|
||||
u16 size;
|
||||
u8 rsvd[3];
|
||||
u8 src;
|
||||
#endif
|
||||
} __packed;
|
||||
|
||||
/* Transmit context mailbox outbox registers
|
||||
@ -101,11 +147,18 @@ struct qlcnic_tx_mbx {
|
||||
* @ctx_id: transmit context id
|
||||
* @state: state of the transmit context
|
||||
*/
|
||||
|
||||
struct qlcnic_tx_mbx_out {
|
||||
u32 host_prod;
|
||||
#if defined(__LITTLE_ENDIAN)
|
||||
u16 ctx_id;
|
||||
u8 state;
|
||||
u8 rsvd;
|
||||
#elif defined(__BIG_ENDIAN)
|
||||
u8 rsvd;
|
||||
u8 state;
|
||||
u16 ctx_id;
|
||||
#endif
|
||||
} __packed;
|
||||
|
||||
static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = {
|
||||
@ -1004,7 +1057,8 @@ static int qlcnic_83xx_add_rings(struct qlcnic_adapter *adapter)
|
||||
sds = &recv_ctx->sds_rings[i];
|
||||
sds->consumer = 0;
|
||||
memset(sds->desc_head, 0, STATUS_DESC_RINGSIZE(sds));
|
||||
sds_mbx.phy_addr = sds->phys_addr;
|
||||
sds_mbx.phy_addr_low = LSD(sds->phys_addr);
|
||||
sds_mbx.phy_addr_high = MSD(sds->phys_addr);
|
||||
sds_mbx.sds_ring_size = sds->num_desc;
|
||||
|
||||
if (adapter->flags & QLCNIC_MSIX_ENABLED)
|
||||
@ -1090,7 +1144,8 @@ int qlcnic_83xx_create_rx_ctx(struct qlcnic_adapter *adapter)
|
||||
sds = &recv_ctx->sds_rings[i];
|
||||
sds->consumer = 0;
|
||||
memset(sds->desc_head, 0, STATUS_DESC_RINGSIZE(sds));
|
||||
sds_mbx.phy_addr = sds->phys_addr;
|
||||
sds_mbx.phy_addr_low = LSD(sds->phys_addr);
|
||||
sds_mbx.phy_addr_high = MSD(sds->phys_addr);
|
||||
sds_mbx.sds_ring_size = sds->num_desc;
|
||||
if (adapter->flags & QLCNIC_MSIX_ENABLED)
|
||||
intrpt_id = ahw->intr_tbl[i].id;
|
||||
@ -1110,13 +1165,15 @@ int qlcnic_83xx_create_rx_ctx(struct qlcnic_adapter *adapter)
|
||||
rds = &recv_ctx->rds_rings[0];
|
||||
rds->producer = 0;
|
||||
memset(&rds_mbx, 0, rds_mbx_size);
|
||||
rds_mbx.phy_addr_reg = rds->phys_addr;
|
||||
rds_mbx.phy_addr_reg_low = LSD(rds->phys_addr);
|
||||
rds_mbx.phy_addr_reg_high = MSD(rds->phys_addr);
|
||||
rds_mbx.reg_ring_sz = rds->dma_size;
|
||||
rds_mbx.reg_ring_len = rds->num_desc;
|
||||
/* Jumbo ring */
|
||||
rds = &recv_ctx->rds_rings[1];
|
||||
rds->producer = 0;
|
||||
rds_mbx.phy_addr_jmb = rds->phys_addr;
|
||||
rds_mbx.phy_addr_jmb_low = LSD(rds->phys_addr);
|
||||
rds_mbx.phy_addr_jmb_high = MSD(rds->phys_addr);
|
||||
rds_mbx.jmb_ring_sz = rds->dma_size;
|
||||
rds_mbx.jmb_ring_len = rds->num_desc;
|
||||
buf = &cmd.req.arg[index];
|
||||
@ -1182,8 +1239,10 @@ int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *adapter,
|
||||
memset(&mbx, 0, sizeof(struct qlcnic_tx_mbx));
|
||||
|
||||
/* setup mailbox inbox registerss */
|
||||
mbx.phys_addr = tx->phys_addr;
|
||||
mbx.cnsmr_index = tx->hw_cons_phys_addr;
|
||||
mbx.phys_addr_low = LSD(tx->phys_addr);
|
||||
mbx.phys_addr_high = MSD(tx->phys_addr);
|
||||
mbx.cnsmr_index_low = LSD(tx->hw_cons_phys_addr);
|
||||
mbx.cnsmr_index_high = MSD(tx->hw_cons_phys_addr);
|
||||
mbx.size = tx->num_desc;
|
||||
if (adapter->flags & QLCNIC_MSIX_ENABLED)
|
||||
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,
|
||||
(adapter->recv_ctx->context_id << 16);
|
||||
|
||||
mv.vlan = le16_to_cpu(vlan_id);
|
||||
memcpy(&mv.mac, addr, ETH_ALEN);
|
||||
mv.mac_addr0 = addr[0];
|
||||
mv.mac_addr1 = addr[1];
|
||||
mv.mac_addr2 = addr[2];
|
||||
mv.mac_addr3 = addr[3];
|
||||
mv.mac_addr4 = addr[4];
|
||||
mv.mac_addr5 = addr[5];
|
||||
buf = &cmd.req.arg[2];
|
||||
memcpy(buf, &mv, sizeof(struct qlcnic_macvlan_mbx));
|
||||
err = qlcnic_issue_cmd(adapter, &cmd);
|
||||
|
@ -94,8 +94,23 @@ struct qlcnic_intrpt_config {
|
||||
};
|
||||
|
||||
struct qlcnic_macvlan_mbx {
|
||||
u8 mac[ETH_ALEN];
|
||||
#if defined(__LITTLE_ENDIAN)
|
||||
u8 mac_addr0;
|
||||
u8 mac_addr1;
|
||||
u8 mac_addr2;
|
||||
u8 mac_addr3;
|
||||
u8 mac_addr4;
|
||||
u8 mac_addr5;
|
||||
u16 vlan;
|
||||
#elif defined(__BIG_ENDIAN)
|
||||
u8 mac_addr3;
|
||||
u8 mac_addr2;
|
||||
u8 mac_addr1;
|
||||
u8 mac_addr0;
|
||||
u16 vlan;
|
||||
u8 mac_addr5;
|
||||
u8 mac_addr4;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct qlc_83xx_fw_info {
|
||||
|
@ -31,6 +31,7 @@ static int qlcnic_83xx_restart_hw(struct qlcnic_adapter *adapter);
|
||||
|
||||
/* Template header */
|
||||
struct qlc_83xx_reset_hdr {
|
||||
#if defined(__LITTLE_ENDIAN)
|
||||
u16 version;
|
||||
u16 signature;
|
||||
u16 size;
|
||||
@ -39,14 +40,31 @@ struct qlc_83xx_reset_hdr {
|
||||
u16 checksum;
|
||||
u16 init_offset;
|
||||
u16 start_offset;
|
||||
#elif defined(__BIG_ENDIAN)
|
||||
u16 signature;
|
||||
u16 version;
|
||||
u16 entries;
|
||||
u16 size;
|
||||
u16 checksum;
|
||||
u16 hdr_size;
|
||||
u16 start_offset;
|
||||
u16 init_offset;
|
||||
#endif
|
||||
} __packed;
|
||||
|
||||
/* Command entry header. */
|
||||
struct qlc_83xx_entry_hdr {
|
||||
u16 cmd;
|
||||
u16 size;
|
||||
u16 count;
|
||||
u16 delay;
|
||||
#if defined(__LITTLE_ENDIAN)
|
||||
u16 cmd;
|
||||
u16 size;
|
||||
u16 count;
|
||||
u16 delay;
|
||||
#elif defined(__BIG_ENDIAN)
|
||||
u16 size;
|
||||
u16 cmd;
|
||||
u16 delay;
|
||||
u16 count;
|
||||
#endif
|
||||
} __packed;
|
||||
|
||||
/* Generic poll command */
|
||||
@ -60,10 +78,17 @@ struct qlc_83xx_rmw {
|
||||
u32 mask;
|
||||
u32 xor_value;
|
||||
u32 or_value;
|
||||
#if defined(__LITTLE_ENDIAN)
|
||||
u8 shl;
|
||||
u8 shr;
|
||||
u8 index_a;
|
||||
u8 rsvd;
|
||||
#elif defined(__BIG_ENDIAN)
|
||||
u8 rsvd;
|
||||
u8 index_a;
|
||||
u8 shr;
|
||||
u8 shl;
|
||||
#endif
|
||||
} __packed;
|
||||
|
||||
/* Generic command with 2 DWORD */
|
||||
|
Loading…
Reference in New Issue
Block a user